mirror of
https://github.com/apache/nuttx.git
synced 2026-09-01 14:43:02 +00:00
boards/risc-v: LCD support on esp32p4-tab5
Adds support for st7121 and st7123 variants for LCD support on the esp32p4-tab5 board. Includes power management though IO expander under 'hmi_power' and new board KConfig options. Signed-off-by: Filipe Cavalcanti <filipe.cavalcanti@espressif.com>
This commit is contained in:
parent
8b73477c5e
commit
2bf531b3f4
13 changed files with 1990 additions and 7 deletions
|
|
@ -5,6 +5,10 @@
|
|||
|
||||
if ARCH_BOARD_ESP32P4_TAB5
|
||||
|
||||
config ESP32P4_TAB5_HMI_POWER
|
||||
bool
|
||||
default n
|
||||
|
||||
config ESP32P4_TAB5_IOEXPANDER
|
||||
bool "Enable the Tab5 board IO Expander"
|
||||
default n
|
||||
|
|
@ -31,4 +35,67 @@ if ESP32P4_TAB5_IOEXPANDER
|
|||
Enable the second IO Expander.
|
||||
endif
|
||||
|
||||
config ESP32P4_TAB5_LCD_POWER
|
||||
bool "LCD / MIPI PHY power and reset path"
|
||||
default n
|
||||
select ESP32P4_TAB5_IOEXPANDER
|
||||
select ESP32P4_TAB5_HMI_POWER
|
||||
---help---
|
||||
At board bring-up (after I2C0 init), enable on-chip LDO channel 3
|
||||
at 2500 mV for VDD_MIPI_DPHY and raise LCD_EN on expander pin P4.
|
||||
|
||||
This does NOT initialize the MIPI-DSI host, the LCD panel, or
|
||||
/dev/fb0 by itself. Enable ESP32P4_TAB5_MIPI_DSI (and
|
||||
ESPRESSIF_MIPI_DSI) to register the host after this power path.
|
||||
Enable ESP32P4_TAB5_LCD for panel initialization + /dev/fb0.
|
||||
|
||||
config ESP32P4_TAB5_MIPI_DSI
|
||||
bool "Register MIPI-DSI host at bring-up"
|
||||
default n
|
||||
depends on ESP32P4_TAB5_LCD_POWER && ESPRESSIF_MIPI_DSI
|
||||
---help---
|
||||
After the LCD power path succeeds, call
|
||||
esp_mipi_dsi_initialize() so the generic MIPI-DSI host is
|
||||
registered (LP DCS/generic transfer ready).
|
||||
|
||||
Does NOT run panel initialization or create /dev/fb0 by itself;
|
||||
enable ESP32P4_TAB5_LCD for that.
|
||||
|
||||
config ESP32P4_TAB5_LCD
|
||||
bool "LCD panel and /dev/fb0"
|
||||
default n
|
||||
depends on ESP32P4_TAB5_MIPI_DSI
|
||||
select DRIVERS_VIDEO
|
||||
select VIDEO_FB
|
||||
select FB_UPDATE
|
||||
---help---
|
||||
Bring up the selected Tab5 MIPI-DSI panel (M5Stack init table and
|
||||
720×1280 RGB565 timings), allocate a PSRAM framebuffer, bind it
|
||||
to the DSI bridge via DW-GDMA, and register /dev/fb0.
|
||||
|
||||
config ESP32P4_TAB5_LCD_APO_TEST
|
||||
bool "All-Pixels-On flash after FB bring-up"
|
||||
default y
|
||||
depends on ESP32P4_TAB5_LCD
|
||||
---help---
|
||||
After /dev/fb0 is ready, force All-Pixels-On for ~1 s, then
|
||||
All-Pixels-Off and restore the solid red test fill.
|
||||
|
||||
choice
|
||||
prompt "Tab5 LCD panel controller"
|
||||
default ESP32P4_TAB5_LCD_ST7121
|
||||
depends on ESP32P4_TAB5_LCD
|
||||
|
||||
config ESP32P4_TAB5_LCD_ST7121
|
||||
bool "ST7121"
|
||||
---help---
|
||||
Use the ST7121 initialization table and display timings.
|
||||
|
||||
config ESP32P4_TAB5_LCD_ST7123
|
||||
bool "ST7123"
|
||||
---help---
|
||||
Use the ST7123 initialization table and display timings.
|
||||
|
||||
endchoice
|
||||
|
||||
endif # ARCH_BOARD_ESP32P4_TAB5
|
||||
|
|
|
|||
|
|
@ -55,18 +55,46 @@
|
|||
|
||||
#define BUTTON_BOOT 35
|
||||
|
||||
/* Display - MIPI-DSI ILI9881C (NOT implemented; pins documented only)
|
||||
/* Display - MIPI-DSI ST7121/ST7123 (M5Stack Tab5 reference timings)
|
||||
*
|
||||
* The DSI data/clock lanes are dedicated MIPI pins (not GPIO-muxed) powered
|
||||
* by VDD_MIPI_DPHY; only the backlight enable is a GPIO. Panel reset is the
|
||||
* board power-on reset (BSP_LCD_RST = NC) driven by IO expander 0x43 P4.
|
||||
* by VDD_MIPI_DPHY (LDO ch3 @ 2500 mV). Backlight enable is GPIO22.
|
||||
* BSP_LCD_RST is NC; LCD_EN / reset control is PI4IOE5V6408 @0x43 P4.
|
||||
*
|
||||
* Enable /dev/fb0 with CONFIG_ESP32P4_TAB5_LCD (see configs/lcd), which
|
||||
* selects power + MIPI host + VIDEO_FB. Select the matching panel with
|
||||
* CONFIG_ESP32P4_TAB5_LCD_ST7121 or CONFIG_ESP32P4_TAB5_LCD_ST7123.
|
||||
*/
|
||||
|
||||
#define TAB5_GPIO_LCD_BL_EN 22 /* Backlight enable -> ME2212 boost EN */
|
||||
|
||||
/* Touch - GT911 (NOT implemented; pins documented only) */
|
||||
#define TAB5_MIPI_DSI_H_RES 720
|
||||
#define TAB5_MIPI_DSI_V_RES 1280
|
||||
#define TAB5_MIPI_DSI_DPI_CLK_MHZ 70
|
||||
#define TAB5_MIPI_DSI_HSYNC_PULSE_WIDTH 2
|
||||
#define TAB5_MIPI_DSI_HSYNC_BACK_PORCH 40
|
||||
#define TAB5_MIPI_DSI_HSYNC_FRONT_PORCH 40
|
||||
#define TAB5_MIPI_DSI_LANES 2
|
||||
|
||||
#define TAB5_GPIO_TP_INT 23 /* GT911 touch interrupt */
|
||||
#ifdef CONFIG_ESP32P4_TAB5_LCD_ST7123
|
||||
# define TAB5_LCD_PANEL_NAME "ST7123"
|
||||
# define TAB5_MIPI_DSI_VSYNC_PULSE_WIDTH 2
|
||||
# define TAB5_MIPI_DSI_VSYNC_BACK_PORCH 8
|
||||
# define TAB5_MIPI_DSI_VSYNC_FRONT_PORCH 220
|
||||
# define TAB5_MIPI_DSI_LANE_BITRATE_MBPS 1000
|
||||
#else
|
||||
# define TAB5_LCD_PANEL_NAME "ST7121"
|
||||
# define TAB5_MIPI_DSI_VSYNC_PULSE_WIDTH 20
|
||||
# define TAB5_MIPI_DSI_VSYNC_BACK_PORCH 24
|
||||
# define TAB5_MIPI_DSI_VSYNC_FRONT_PORCH 200
|
||||
# define TAB5_MIPI_DSI_LANE_BITRATE_MBPS 965
|
||||
#endif
|
||||
|
||||
/* Touch - ST7121/ST7123 TDDI @0x55 (NOT implemented; INT GPIO23). Older
|
||||
* ILI9881 units used GT911 @0x14 on the same INT pin.
|
||||
*/
|
||||
|
||||
#define TAB5_GPIO_TP_INT 23 /* Touch interrupt */
|
||||
|
||||
/* Audio - ES8388 codec (out) + ES7210 mic array (in), I2S (pins only) */
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,20 @@ set(SRCS esp32p4_boot.c esp32p4_bringup.c)
|
|||
|
||||
if(CONFIG_ESP32P4_TAB5_IOEXPANDER)
|
||||
list(APPEND SRCS esp32p4_ioexpander.c)
|
||||
endif
|
||||
endif()
|
||||
|
||||
if(CONFIG_ESP32P4_TAB5_HMI_POWER)
|
||||
list(APPEND SRCS esp32p4_hmi_power.c)
|
||||
endif()
|
||||
|
||||
if(CONFIG_ESP32P4_TAB5_LCD)
|
||||
list(APPEND SRCS esp32p4_display.c esp32p4_mipi_dpi.c)
|
||||
if(CONFIG_ESP32P4_TAB5_LCD_ST7121)
|
||||
list(APPEND SRCS esp32p4_lcd_st7121.c)
|
||||
elseif(CONFIG_ESP32P4_TAB5_LCD_ST7123)
|
||||
list(APPEND SRCS esp32p4_lcd_st7123.c)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(CONFIG_BOARDCTL)
|
||||
if(CONFIG_BOARDCTL_RESET)
|
||||
|
|
|
|||
|
|
@ -28,6 +28,19 @@ ifeq ($(CONFIG_ESP32P4_TAB5_IOEXPANDER),y)
|
|||
CSRCS += esp32p4_ioexpander.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_ESP32P4_TAB5_HMI_POWER),y)
|
||||
CSRCS += esp32p4_hmi_power.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_ESP32P4_TAB5_LCD),y)
|
||||
CSRCS += esp32p4_display.c esp32p4_mipi_dpi.c
|
||||
ifeq ($(CONFIG_ESP32P4_TAB5_LCD_ST7121),y)
|
||||
CSRCS += esp32p4_lcd_st7121.c
|
||||
else ifeq ($(CONFIG_ESP32P4_TAB5_LCD_ST7123),y)
|
||||
CSRCS += esp32p4_lcd_st7123.c
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_BOARDCTL),y)
|
||||
ifeq ($(CONFIG_BOARDCTL_RESET),y)
|
||||
CSRCS += esp32p4_reset.c
|
||||
|
|
|
|||
|
|
@ -28,6 +28,13 @@
|
|||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <nuttx/compiler.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef CONFIG_ESPRESSIF_MIPI_DSI
|
||||
# include "espressif/esp_mipi_dsi.h"
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
|
|
@ -56,6 +63,108 @@
|
|||
|
||||
int esp_bringup(void);
|
||||
|
||||
#ifdef CONFIG_ESP32P4_TAB5_LCD_POWER
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tab5_mipi_phy_power
|
||||
*
|
||||
* Description:
|
||||
* Enable or disable LDO channel 3 (VDD_MIPI_DPHY @ 2500 mV).
|
||||
*
|
||||
* Input Parameters:
|
||||
* on - True to enable the LDO channel, false to disable it.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero on success, -1 on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int tab5_mipi_phy_power(bool on);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tab5_lcd_enable
|
||||
*
|
||||
* Description:
|
||||
* Drive PI4IOE P4 (BSP_LCD_EN). true = enable (high).
|
||||
*
|
||||
* Input Parameters:
|
||||
* enable - True to enable the LCD rail, false to disable it.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero on success, -1 on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int tab5_lcd_enable(bool enable);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tab5_lcd_backlight
|
||||
*
|
||||
* Description:
|
||||
* Drive backlight enable GPIO22 (ME2212 boost EN).
|
||||
*
|
||||
* Input Parameters:
|
||||
* on - True to enable the backlight, false to disable it.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero on success, -1 on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int tab5_lcd_backlight(bool on);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tab5_lcd_power_init
|
||||
*
|
||||
* Description:
|
||||
* Power MIPI PHY LDO, init PI4IOE, and enable LCD (P4 high).
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero on success, -1 on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int tab5_lcd_power_init(void);
|
||||
|
||||
#endif /* CONFIG_ESP32P4_TAB5_LCD_POWER */
|
||||
|
||||
#ifdef CONFIG_ESP32P4_TAB5_LCD
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tab5_fb_reload_test_pattern
|
||||
*
|
||||
* Description:
|
||||
* Re-fill the plane with the bring-up test color and cache write-back.
|
||||
* Call after fb_register(): the generic FB driver memset()s the plane
|
||||
* and would otherwise leave a black DMA buffer.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero on success, -1 on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int tab5_fb_reload_test_pattern(void);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tab5_mipi_dsi_dpi_config
|
||||
*
|
||||
* Description:
|
||||
* Fill DPI timing for the selected Tab5 ST712x panel. Arch
|
||||
* host has no panel defaults — board code supplies this to
|
||||
* esp_mipi_dsi_configure_dpi().
|
||||
*
|
||||
* Input Parameters:
|
||||
* cfg - Pointer to the DPI configuration structure.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero on success, -1 on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void tab5_mipi_dsi_dpi_config(FAR struct esp_mipi_dsi_dpi_config_s *cfg);
|
||||
|
||||
#endif /* CONFIG_ESP32P4_TAB5_LCD */
|
||||
|
||||
#ifdef CONFIG_ESP32P4_TAB5_IOEXPANDER
|
||||
/****************************************************************************
|
||||
* Name: tab5_pi4ioe_init
|
||||
|
|
|
|||
|
|
@ -42,6 +42,14 @@
|
|||
# include "esp_board_i2c.h"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ESP32P4_TAB5_MIPI_DSI
|
||||
# include "espressif/esp_mipi_dsi.h"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ESP32P4_TAB5_LCD
|
||||
# include <nuttx/video/fb.h>
|
||||
#endif
|
||||
|
||||
#include <arch/board/board.h>
|
||||
|
||||
#include "esp32p4-tab5.h"
|
||||
|
|
@ -103,11 +111,66 @@ int esp_bringup(void)
|
|||
ret = tab5_pi4ioe_init();
|
||||
if (ret < 0)
|
||||
{
|
||||
syslog(LOG_ERR, "Failed to initialize Tab5 IO expanders: %d\n", ret);
|
||||
syslog(LOG_ERR, "ERROR: failed to init IO expanders: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ESP32P4_TAB5_LCD_POWER
|
||||
/* MIPI PHY LDO + PI4IOE LCD_EN (before optional DSI host) */
|
||||
|
||||
ret = tab5_lcd_power_init();
|
||||
if (ret < 0)
|
||||
{
|
||||
syslog(LOG_ERR, "ERROR: failed to init LCD power path: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ESP32P4_TAB5_MIPI_DSI
|
||||
/* Tab5 ST712x bus: 2 lanes @ board.h bitrate. */
|
||||
|
||||
struct esp_mipi_dsi_bus_config_s bus_cfg =
|
||||
{
|
||||
.num_data_lanes = TAB5_MIPI_DSI_LANES,
|
||||
.lane_bit_rate_mbps = TAB5_MIPI_DSI_LANE_BITRATE_MBPS,
|
||||
};
|
||||
|
||||
ret = esp_mipi_dsi_initialize(&bus_cfg);
|
||||
if (ret < 0)
|
||||
{
|
||||
syslog(LOG_ERR, "ERROR: failed to init MIPI-DSI host: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
syslog(LOG_INFO, "Tab5: MIPI-DSI host registered\n");
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ESP32P4_TAB5_LCD
|
||||
/* Selected panel DCS + DPI + DW-GDMA FB → /dev/fb0 */
|
||||
|
||||
ret = fb_register(0, 0);
|
||||
if (ret < 0)
|
||||
{
|
||||
syslog(LOG_ERR, "ERROR: failed to register /dev/fb0: %d\n", ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* fb_register() clears the plane; restore test red for DMA. */
|
||||
|
||||
ret = tab5_fb_reload_test_pattern();
|
||||
if (ret < 0)
|
||||
{
|
||||
syslog(LOG_ERR,
|
||||
"ERROR: failed to reload FB test pattern: %d\n", ret);
|
||||
}
|
||||
|
||||
syslog(LOG_INFO, "/dev/fb0 registered (%s)\n",
|
||||
TAB5_LCD_PANEL_NAME);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FS_TMPFS
|
||||
/* Mount the tmpfs file system */
|
||||
|
||||
|
|
|
|||
485
boards/risc-v/esp32p4/esp32p4-tab5/src/esp32p4_display.c
Normal file
485
boards/risc-v/esp32p4/esp32p4-tab5/src/esp32p4_display.c
Normal file
|
|
@ -0,0 +1,485 @@
|
|||
/****************************************************************************
|
||||
* boards/risc-v/esp32p4/esp32p4-tab5/src/esp32p4_display.c
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/* Tab5 display / framebuffer glue (PinePhone-style up_fbinitialize split).
|
||||
*
|
||||
* Sequence (ESP-IDF DPI panel + selected ST712x controller):
|
||||
* 1. Allocate RGB565 FB (PSRAM)
|
||||
* 2. Host already registered by bringup
|
||||
* 3. configure_dpi -> panel DCS -> bind FB -> video_start -> display_on
|
||||
* 4. Backlight on
|
||||
* 5. Optional All-Pixels-On bring-up flash
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/compiler.h>
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/video/fb.h>
|
||||
#include <nuttx/video/mipi_display.h>
|
||||
#include <nuttx/video/mipi_dsi.h>
|
||||
|
||||
#include <arch/board/board.h>
|
||||
|
||||
#include "espressif/esp_mipi_dsi.h"
|
||||
|
||||
#include "esp32p4-tab5.h"
|
||||
|
||||
#ifdef CONFIG_ESP32P4_TAB5_LCD_ST7123
|
||||
# include "esp32p4_lcd_st7123.h"
|
||||
# define tab5_panel_initialize tab5_st7123_initialize
|
||||
#else
|
||||
# include "esp32p4_lcd_st7121.h"
|
||||
# define tab5_panel_initialize tab5_st7121_initialize
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define TAB5_FB_BPP 16
|
||||
#define TAB5_FB_WIDTH TAB5_MIPI_DSI_H_RES
|
||||
#define TAB5_FB_HEIGHT TAB5_MIPI_DSI_V_RES
|
||||
#define TAB5_FB_STRIDE (TAB5_FB_WIDTH * (TAB5_FB_BPP / 8))
|
||||
#define TAB5_FB_SIZE (TAB5_FB_STRIDE * TAB5_FB_HEIGHT)
|
||||
|
||||
#define TAB5_FB_TEST_COLOR 0xf800
|
||||
|
||||
#define TAB5_DCS_ALL_PIXELS_ON 0x23
|
||||
#define TAB5_DCS_ALL_PIXELS_OFF 0x22
|
||||
#define TAB5_APO_TEST_MS 1000
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
static int tab5_getvideoinfo(FAR struct fb_vtable_s *vtable,
|
||||
FAR struct fb_videoinfo_s *vinfo);
|
||||
static int tab5_getplaneinfo(FAR struct fb_vtable_s *vtable, int planeno,
|
||||
FAR struct fb_planeinfo_s *pinfo);
|
||||
#ifdef CONFIG_FB_UPDATE
|
||||
static int tab5_updatearea(FAR struct fb_vtable_s *vtable,
|
||||
FAR const struct fb_area_s *area);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static struct fb_vtable_s g_tab5_vtable =
|
||||
{
|
||||
.getvideoinfo = tab5_getvideoinfo,
|
||||
.getplaneinfo = tab5_getplaneinfo,
|
||||
#ifdef CONFIG_FB_UPDATE
|
||||
.updatearea = tab5_updatearea,
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct fb_videoinfo_s g_tab5_video =
|
||||
{
|
||||
.fmt = FB_FMT_RGB16_565,
|
||||
.xres = TAB5_FB_WIDTH,
|
||||
.yres = TAB5_FB_HEIGHT,
|
||||
.nplanes = 1,
|
||||
};
|
||||
|
||||
static struct fb_planeinfo_s g_tab5_plane =
|
||||
{
|
||||
.fbmem = NULL,
|
||||
.fblen = TAB5_FB_SIZE,
|
||||
.stride = TAB5_FB_STRIDE,
|
||||
.display = 0,
|
||||
.bpp = TAB5_FB_BPP,
|
||||
.xres_virtual = TAB5_FB_WIDTH,
|
||||
.yres_virtual = TAB5_FB_HEIGHT,
|
||||
.xoffset = 0,
|
||||
.yoffset = 0,
|
||||
};
|
||||
|
||||
static FAR uint16_t *g_tab5_fb;
|
||||
static bool g_tab5_fb_ready;
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tab5_getvideoinfo
|
||||
*
|
||||
* Description:
|
||||
* Return the video information.
|
||||
*
|
||||
* Input Parameters:
|
||||
* vtable - The vtable.
|
||||
* vinfo - The video information.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero on success.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int tab5_getvideoinfo(FAR struct fb_vtable_s *vtable,
|
||||
FAR struct fb_videoinfo_s *vinfo)
|
||||
{
|
||||
DEBUGASSERT(vtable != NULL && vtable == &g_tab5_vtable && vinfo != NULL);
|
||||
memcpy(vinfo, &g_tab5_video, sizeof(*vinfo));
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tab5_getplaneinfo
|
||||
*
|
||||
* Description:
|
||||
* Return the plane information.
|
||||
*
|
||||
* Input Parameters:
|
||||
* vtable - The vtable.
|
||||
* planeno - The plane number.
|
||||
* pinfo - The plane information.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero on success, -EINVAL if the plane number is invalid.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int tab5_getplaneinfo(FAR struct fb_vtable_s *vtable, int planeno,
|
||||
FAR struct fb_planeinfo_s *pinfo)
|
||||
{
|
||||
DEBUGASSERT(vtable != NULL && vtable == &g_tab5_vtable && pinfo != NULL);
|
||||
|
||||
if (planeno != 0 || g_tab5_plane.fbmem == NULL)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
memcpy(pinfo, &g_tab5_plane, sizeof(*pinfo));
|
||||
return OK;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_FB_UPDATE
|
||||
/****************************************************************************
|
||||
* Name: tab5_updatearea
|
||||
*
|
||||
* Description:
|
||||
* Update a region of the framebuffer.
|
||||
*
|
||||
* Input Parameters:
|
||||
* vtable - The vtable.
|
||||
* area - The area to update.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero on success, -EAGAIN if the framebuffer is not ready,
|
||||
* -EINVAL if the area is out of bounds.
|
||||
****************************************************************************/
|
||||
|
||||
static int tab5_updatearea(FAR struct fb_vtable_s *vtable,
|
||||
FAR const struct fb_area_s *area)
|
||||
{
|
||||
size_t offset;
|
||||
size_t len;
|
||||
|
||||
DEBUGASSERT(vtable != NULL && vtable == &g_tab5_vtable);
|
||||
|
||||
if (g_tab5_fb == NULL)
|
||||
{
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
if (area == NULL)
|
||||
{
|
||||
return esp_mipi_dsi_flush_framebuffer(g_tab5_fb, TAB5_FB_SIZE);
|
||||
}
|
||||
|
||||
if (area->y >= TAB5_FB_HEIGHT || area->x >= TAB5_FB_WIDTH)
|
||||
{
|
||||
return OK;
|
||||
}
|
||||
|
||||
offset = (size_t)area->y * TAB5_FB_STRIDE +
|
||||
(size_t)area->x * (TAB5_FB_BPP / 8);
|
||||
len = (size_t)area->h * TAB5_FB_STRIDE;
|
||||
if (offset + len > TAB5_FB_SIZE)
|
||||
{
|
||||
len = TAB5_FB_SIZE - offset;
|
||||
}
|
||||
|
||||
return esp_mipi_dsi_flush_framebuffer((FAR uint8_t *)g_tab5_fb + offset,
|
||||
len);
|
||||
}
|
||||
#endif /* CONFIG_FB_UPDATE */
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tab5_fb_fill
|
||||
*
|
||||
* Description:
|
||||
* Fill the framebuffer with a given color.
|
||||
*
|
||||
* Input Parameters:
|
||||
* color - The color to fill the framebuffer with.
|
||||
*
|
||||
* Returned Value:
|
||||
* None.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void tab5_fb_fill(uint16_t color)
|
||||
{
|
||||
size_t i;
|
||||
size_t npix = (size_t)TAB5_FB_WIDTH * TAB5_FB_HEIGHT;
|
||||
int ret;
|
||||
|
||||
for (i = 0; i < npix; i++)
|
||||
{
|
||||
g_tab5_fb[i] = color;
|
||||
}
|
||||
|
||||
ret = esp_mipi_dsi_flush_framebuffer(g_tab5_fb, TAB5_FB_SIZE);
|
||||
if (ret < 0)
|
||||
{
|
||||
syslog(LOG_ERR, "ERROR: FB cache C2M sync failed: %d\n", ret);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_fbinitialize
|
||||
*
|
||||
* Description:
|
||||
* Initialize the framebuffer.
|
||||
*
|
||||
* Input Parameters:
|
||||
* display - The display number.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero on success, -ENODEV on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int up_fbinitialize(int display)
|
||||
{
|
||||
FAR struct mipi_dsi_host *host;
|
||||
FAR struct mipi_dsi_device *device;
|
||||
struct esp_mipi_dsi_dpi_config_s dpi;
|
||||
int ret;
|
||||
|
||||
if (display != 0)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (g_tab5_fb_ready)
|
||||
{
|
||||
return OK;
|
||||
}
|
||||
|
||||
g_tab5_fb = kumm_memalign(64, TAB5_FB_SIZE);
|
||||
if (g_tab5_fb == NULL)
|
||||
{
|
||||
syslog(LOG_ERR,
|
||||
"ERROR: FB alloc failed (%u bytes; enable PSRAM)\n",
|
||||
(unsigned int)TAB5_FB_SIZE);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memset(g_tab5_fb, 0, TAB5_FB_SIZE);
|
||||
g_tab5_plane.fbmem = g_tab5_fb;
|
||||
|
||||
host = esp_mipi_dsi_host_get();
|
||||
if (host == NULL)
|
||||
{
|
||||
syslog(LOG_ERR,
|
||||
"ERROR: MIPI-DSI host not ready "
|
||||
"(enable ESP32P4_TAB5_MIPI_DSI)\n");
|
||||
ret = -EAGAIN;
|
||||
goto errout_fb;
|
||||
}
|
||||
|
||||
/* IDF order: DPI config before panel DCS; display_on after video_start. */
|
||||
|
||||
syslog(LOG_INFO, "Configuring DPI...\n");
|
||||
tab5_mipi_dsi_dpi_config(&dpi);
|
||||
ret = esp_mipi_dsi_configure_dpi(&dpi);
|
||||
if (ret < 0)
|
||||
{
|
||||
syslog(LOG_ERR, "ERROR: configure_dpi failed: %d\n", ret);
|
||||
goto errout_fb;
|
||||
}
|
||||
|
||||
syslog(LOG_INFO, "%s panel init...\n",
|
||||
TAB5_LCD_PANEL_NAME);
|
||||
device = tab5_panel_initialize(host);
|
||||
if (device == NULL)
|
||||
{
|
||||
ret = -EIO;
|
||||
goto errout_fb;
|
||||
}
|
||||
|
||||
ret = esp_mipi_dsi_bind_framebuffer(g_tab5_fb, TAB5_FB_SIZE,
|
||||
TAB5_FB_WIDTH, TAB5_FB_HEIGHT,
|
||||
TAB5_FB_BPP);
|
||||
if (ret < 0)
|
||||
{
|
||||
syslog(LOG_ERR, "ERROR: bind_framebuffer failed: %d\n", ret);
|
||||
goto errout_fb;
|
||||
}
|
||||
|
||||
tab5_fb_fill(TAB5_FB_TEST_COLOR);
|
||||
|
||||
ret = mipi_dsi_dcs_exit_sleep_mode(device);
|
||||
if (ret < 0)
|
||||
{
|
||||
syslog(LOG_ERR, "ERROR: pre-video sleep_out failed: %d\n",
|
||||
ret);
|
||||
goto errout_fb;
|
||||
}
|
||||
|
||||
up_mdelay(120);
|
||||
|
||||
syslog(LOG_INFO, "Starting video...\n");
|
||||
ret = esp_mipi_dsi_video_start();
|
||||
if (ret < 0)
|
||||
{
|
||||
syslog(LOG_ERR, "ERROR: video_start failed: %d\n", ret);
|
||||
goto errout_fb;
|
||||
}
|
||||
|
||||
ret = mipi_dsi_dcs_set_display_on(device);
|
||||
if (ret < 0)
|
||||
{
|
||||
syslog(LOG_ERR, "ERROR: post-video display_on failed: %d\n",
|
||||
ret);
|
||||
goto errout_fb;
|
||||
}
|
||||
|
||||
tab5_fb_fill(TAB5_FB_TEST_COLOR);
|
||||
|
||||
ret = tab5_lcd_backlight(true);
|
||||
if (ret < 0)
|
||||
{
|
||||
syslog(LOG_ERR, "ERROR: backlight failed: %d\n", ret);
|
||||
}
|
||||
|
||||
g_tab5_fb_ready = true;
|
||||
syslog(LOG_INFO,
|
||||
"/dev/fb0 ready %ux%u RGB565 @ %p\n",
|
||||
TAB5_FB_WIDTH, TAB5_FB_HEIGHT, g_tab5_fb);
|
||||
|
||||
#ifdef CONFIG_ESP32P4_TAB5_LCD_APO_TEST
|
||||
/* White flash proves DCS/BL; then restore normal mode + red FB. */
|
||||
|
||||
mipi_dsi_dcs_write(device, TAB5_DCS_ALL_PIXELS_ON, NULL, 0);
|
||||
up_mdelay(TAB5_APO_TEST_MS);
|
||||
mipi_dsi_dcs_write(device, TAB5_DCS_ALL_PIXELS_OFF, NULL, 0);
|
||||
mipi_dsi_dcs_write(device, MIPI_DCS_ENTER_NORMAL_MODE, NULL, 0);
|
||||
mipi_dsi_dcs_set_display_on(device);
|
||||
tab5_fb_fill(TAB5_FB_TEST_COLOR);
|
||||
#endif
|
||||
|
||||
return OK;
|
||||
|
||||
errout_fb:
|
||||
kumm_free(g_tab5_fb);
|
||||
g_tab5_fb = NULL;
|
||||
g_tab5_plane.fbmem = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_fbgetvplane
|
||||
*
|
||||
* Description:
|
||||
* Return the framebuffer vtable.
|
||||
*
|
||||
* Input Parameters:
|
||||
* display - The display number.
|
||||
* vplane - The vplane number.
|
||||
*
|
||||
* Returned Value:
|
||||
* Pointer to the vtable on success, NULL on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR struct fb_vtable_s *up_fbgetvplane(int display, int vplane)
|
||||
{
|
||||
if (display != 0 || vplane != 0 || !g_tab5_fb_ready)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &g_tab5_vtable;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_fbuninitialize
|
||||
*
|
||||
* Description:
|
||||
* Uninitialize the framebuffer.
|
||||
*
|
||||
* Input Parameters:
|
||||
* display - The display number.
|
||||
*
|
||||
* Returned Value:
|
||||
* None.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_fbuninitialize(int display)
|
||||
{
|
||||
UNUSED(display);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tab5_fb_reload_test_pattern
|
||||
*
|
||||
* Description:
|
||||
* Call after fb_register(): the generic FB driver memset()s the
|
||||
* framebuffer and would otherwise leave a black DMA buffer.
|
||||
* This sets the framebuffer to the test color (red).
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero on success, -EAGAIN on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int tab5_fb_reload_test_pattern(void)
|
||||
{
|
||||
if (!g_tab5_fb_ready || g_tab5_fb == NULL)
|
||||
{
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
tab5_fb_fill(TAB5_FB_TEST_COLOR);
|
||||
return OK;
|
||||
}
|
||||
187
boards/risc-v/esp32p4/esp32p4-tab5/src/esp32p4_hmi_power.c
Normal file
187
boards/risc-v/esp32p4/esp32p4-tab5/src/esp32p4_hmi_power.c
Normal file
|
|
@ -0,0 +1,187 @@
|
|||
/****************************************************************************
|
||||
* boards/risc-v/esp32p4/esp32p4-tab5/src/esp32p4_hmi_power.c
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <nuttx/sched.h>
|
||||
|
||||
#include "espressif/esp_ldo.h"
|
||||
#include "espressif/esp_gpio.h"
|
||||
|
||||
#include "esp32p4-tab5.h"
|
||||
#include <arch/board/board.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* MIPI PHY LDO channel and voltage */
|
||||
|
||||
#define ESP_LDO_MIPI_PHY_CHAN 3
|
||||
#define ESP_LDO_MIPI_PHY_VOLTAGE_MV 2500
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static struct esp_ldo_config_t g_mipi_phy_ldo_config =
|
||||
{
|
||||
.chan_id = ESP_LDO_MIPI_PHY_CHAN,
|
||||
.voltage_mv = ESP_LDO_MIPI_PHY_VOLTAGE_MV,
|
||||
.handler = NULL,
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tab5_mipi_phy_power
|
||||
*
|
||||
* Description:
|
||||
* Enable or disable the MIPI PHY LDO.
|
||||
*
|
||||
* Input Parameters:
|
||||
* on - True to enable the MIPI PHY LDO, false to disable it.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero on success, -1 on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int tab5_mipi_phy_power(bool on)
|
||||
{
|
||||
int ret = OK;
|
||||
if (on)
|
||||
{
|
||||
ret = esp_ldo_channel_acquire(&g_mipi_phy_ldo_config);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = esp_ldo_channel_release(&g_mipi_phy_ldo_config);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tab5_lcd_enable
|
||||
*
|
||||
* Description:
|
||||
* Enable or disable the LCD rail via IO Expander (low).
|
||||
*
|
||||
* Input Parameters:
|
||||
* enable - True to enable the LCD rail, false to disable it.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero on success, -1 on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int tab5_lcd_enable(bool enable)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = tab5_pi4ioe_low_write_pin(TAB5_LCD_EN_PIN, enable);
|
||||
if (ret < 0)
|
||||
{
|
||||
syslog(LOG_ERR,
|
||||
"ERROR: failed to write LCD_EN pin: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
syslog(LOG_INFO, "LCD %s\n", enable ? "enabled" : "disabled");
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tab5_lcd_backlight
|
||||
*
|
||||
* Description:
|
||||
* Configure GPIO22 as output and drive the backlight enable.
|
||||
*
|
||||
* Input Parameters:
|
||||
* on - True to enable the backlight, false to disable it.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero on success, -1 on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int tab5_lcd_backlight(bool on)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = esp_configgpio(TAB5_GPIO_LCD_BL_EN, OUTPUT);
|
||||
if (ret < 0)
|
||||
{
|
||||
syslog(LOG_ERR, "ERROR: failed to configure backlight GPIO%d: %d\n",
|
||||
TAB5_GPIO_LCD_BL_EN, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_gpiowrite(TAB5_GPIO_LCD_BL_EN, on);
|
||||
syslog(LOG_INFO, "Backlight %s\n", on ? "enabled" : "disabled");
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tab5_lcd_power_init
|
||||
*
|
||||
* Description:
|
||||
* Power MIPI PHY LDO, init PI4IOE, and enable LCD (P4 high).
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero on success, -1 on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int tab5_lcd_power_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = tab5_mipi_phy_power(true);
|
||||
if (ret < 0)
|
||||
{
|
||||
syslog(LOG_ERR, "ERROR: failed to power on MIPI PHY: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = tab5_lcd_enable(true);
|
||||
if (ret < 0)
|
||||
{
|
||||
syslog(LOG_ERR, "ERROR: failed to enable LCD rail: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
syslog(LOG_INFO, "LCD power/reset path ready\n");
|
||||
return OK;
|
||||
}
|
||||
375
boards/risc-v/esp32p4/esp32p4-tab5/src/esp32p4_lcd_st7121.c
Normal file
375
boards/risc-v/esp32p4/esp32p4-tab5/src/esp32p4_lcd_st7121.c
Normal file
|
|
@ -0,0 +1,375 @@
|
|||
/****************************************************************************
|
||||
* boards/risc-v/esp32p4/esp32p4-tab5/src/esp32p4_lcd_st7121.c
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/* ST7121 panel bring-up for M5Stack Tab5.
|
||||
*
|
||||
* Init init table sourced from https://github.com/espressif/esp-iot-solution
|
||||
* under components/display/lcd/esp_lcd_st7121/esp_lcd_st7121.c.
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/video/mipi_dsi.h>
|
||||
|
||||
#include <arch/board/board.h>
|
||||
|
||||
#include "esp32p4-tab5.h"
|
||||
#include "esp32p4_lcd_st7121.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define ST7121_NAME "st7121"
|
||||
#define ST7121_COMMAND_DELAY_MS 5
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
struct st7121_init_cmd_s
|
||||
{
|
||||
uint8_t cmd;
|
||||
FAR const uint8_t *data;
|
||||
uint8_t len;
|
||||
uint16_t delay_ms;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static const uint8_t g_st7121_cmd_60a[] =
|
||||
{
|
||||
0x71, 0x21, 0xa2
|
||||
};
|
||||
|
||||
static const uint8_t g_st7121_cmd_60b[] =
|
||||
{
|
||||
0x71, 0x21, 0xa3
|
||||
};
|
||||
|
||||
static const uint8_t g_st7121_cmd_60c[] =
|
||||
{
|
||||
0x71, 0x21, 0xa4
|
||||
};
|
||||
|
||||
static const uint8_t g_st7121_cmd_78[] =
|
||||
{
|
||||
0x21
|
||||
};
|
||||
|
||||
static const uint8_t g_st7121_cmd_79[] =
|
||||
{
|
||||
0xef
|
||||
};
|
||||
|
||||
static const uint8_t g_st7121_cmd_a4[] =
|
||||
{
|
||||
0x31
|
||||
};
|
||||
|
||||
static const uint8_t g_st7121_cmd_b7[] =
|
||||
{
|
||||
0x00, 0x00, 0x5f, 0x5f, 0x44, 0x1a
|
||||
};
|
||||
|
||||
static const uint8_t g_st7121_cmd_b0[] =
|
||||
{
|
||||
0x22, 0x6b, 0x11, 0x89, 0x25, 0x43, 0x43
|
||||
};
|
||||
|
||||
static const uint8_t g_st7121_cmd_bf[] =
|
||||
{
|
||||
0xa7, 0xa7
|
||||
};
|
||||
|
||||
static const uint8_t g_st7121_cmd_a5[] =
|
||||
{
|
||||
0xf0, 0x03
|
||||
};
|
||||
|
||||
static const uint8_t g_st7121_cmd_d7[] =
|
||||
{
|
||||
0x10, 0x2c, 0x14, 0x2a, 0x80, 0x80
|
||||
};
|
||||
|
||||
static const uint8_t g_st7121_cmd_90[] =
|
||||
{
|
||||
0x71, 0x23, 0x5a, 0x20, 0x24, 0x11, 0x21
|
||||
};
|
||||
|
||||
static const uint8_t g_st7121_cmd_a3[] =
|
||||
{
|
||||
0x80, 0x01, 0x8c, 0xff, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x00,
|
||||
0x00, 0x1e, 0x5c, 0x1e, 0x80, 0x10, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x46, 0x00, 0x00, 0x1e, 0x5c, 0x1e, 0x80, 0x10, 0xef, 0x58, 0x00,
|
||||
0x00, 0x00, 0xff
|
||||
};
|
||||
|
||||
static const uint8_t g_st7121_cmd_a6[] =
|
||||
{
|
||||
0x0a, 0x00, 0x24, 0x71, 0x36, 0x00, 0x00, 0x00, 0x68, 0x68, 0x91, 0xff,
|
||||
0x00, 0x24, 0x71, 0x37, 0x00, 0x00, 0x00, 0x68, 0x68, 0x91, 0xff, 0x00,
|
||||
0x24, 0x71, 0x00, 0x00, 0x00, 0x00, 0x68, 0x68, 0x91, 0xff, 0x00, 0x2c,
|
||||
0x71, 0x00, 0x01, 0x00, 0x00, 0x68, 0x68, 0xff, 0xff, 0x00, 0x08, 0x80,
|
||||
0x08, 0x80, 0x06, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
static const uint8_t g_st7121_cmd_a7[] =
|
||||
{
|
||||
0x1a, 0x1a, 0xc0, 0x64, 0x40, 0x04, 0x15, 0x40, 0x00, 0x40, 0x00, 0x68,
|
||||
0x68, 0x91, 0xff, 0x08, 0x80, 0x64, 0x40, 0x26, 0x37, 0x40, 0x00, 0x00,
|
||||
0x00, 0x68, 0x68, 0x91, 0xff, 0x08, 0x80, 0x64, 0x40, 0x8c, 0x9d, 0x40,
|
||||
0x00, 0x00, 0x00, 0x68, 0x68, 0x91, 0xff, 0x08, 0x80, 0x64, 0x40, 0xae,
|
||||
0xbf, 0x00, 0x00, 0x20, 0x00, 0x68, 0x68, 0x91, 0xff, 0x08, 0x80, 0x79
|
||||
};
|
||||
|
||||
static const uint8_t g_st7121_cmd_ac[] =
|
||||
{
|
||||
0x1d, 0x18, 0x19, 0x1d, 0x18, 0x19, 0x04, 0x1c, 0x1d, 0x08, 0x0a, 0x10,
|
||||
0x12, 0x0c, 0x0e, 0x14, 0x16, 0x00, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x18,
|
||||
0x19, 0x1d, 0x18, 0x19, 0x06, 0x1c, 0x1d, 0x09, 0x0b, 0x11, 0x13, 0x0d,
|
||||
0x0f, 0x15, 0x17, 0x02, 0x1d, 0x1d, 0x1d, 0x1d
|
||||
};
|
||||
|
||||
static const uint8_t g_st7121_cmd_ad[] =
|
||||
{
|
||||
0x0c, 0x40, 0x46, 0x00, 0x07, 0x4b, 0x4b, 0xff, 0xff, 0xf0, 0x40, 0x0e,
|
||||
0x01, 0x07, 0x42, 0x42, 0xff, 0xff, 0x01, 0x00, 0x00, 0xff, 0xff, 0xff,
|
||||
0xff
|
||||
};
|
||||
|
||||
static const uint8_t g_st7121_cmd_ae[] =
|
||||
{
|
||||
0xf0, 0xff, 0x03, 0xf0, 0xff, 0x03, 0x00
|
||||
};
|
||||
|
||||
static const uint8_t g_st7121_cmd_b2[] =
|
||||
{
|
||||
0x15, 0x19, 0x05, 0x23, 0x49, 0x2d, 0x03, 0x2e, 0x5c, 0xd2, 0xff, 0x10,
|
||||
0x60, 0xfd, 0x20, 0xc0, 0x00
|
||||
};
|
||||
|
||||
static const uint8_t g_st7121_cmd_e8[] =
|
||||
{
|
||||
0x20, 0x60, 0x04, 0x8e, 0x8e, 0x3e, 0x04, 0xdc, 0xdc, 0x3e, 0x06, 0xfa,
|
||||
0x26, 0x3e
|
||||
};
|
||||
|
||||
static const uint8_t g_st7121_cmd_75[] =
|
||||
{
|
||||
0x03, 0x04
|
||||
};
|
||||
|
||||
static const uint8_t g_st7121_cmd_e7[] =
|
||||
{
|
||||
0x4b, 0x00, 0x00, 0xbe, 0x4b, 0x8c, 0x20, 0x1a, 0xf0, 0x7d, 0x14, 0x7d,
|
||||
0x14, 0x7d, 0x14, 0x7d, 0x14, 0xff, 0x00, 0x32, 0x30, 0x73, 0x00, 0x00,
|
||||
0xc8, 0x6a, 0xff, 0x5a, 0x64, 0x38, 0x88, 0x15, 0xb1, 0x01, 0x01, 0x64,
|
||||
0x01, 0x01, 0x7c, 0xff, 0x1a, 0x51
|
||||
};
|
||||
|
||||
static const uint8_t g_st7121_cmd_e1[] =
|
||||
{
|
||||
0x0c, 0x0c
|
||||
};
|
||||
|
||||
static const uint8_t g_st7121_cmd_ea[] =
|
||||
{
|
||||
0x15, 0x00, 0x01
|
||||
};
|
||||
|
||||
static const uint8_t g_st7121_cmd_c8[] =
|
||||
{
|
||||
0x00, 0x00, 0x04, 0x08, 0x10, 0x00, 0x1f, 0x01, 0x39, 0x3e, 0x00, 0x78,
|
||||
0x06, 0xe2, 0x02, 0x11, 0x33, 0x01, 0x7a, 0x0d, 0x21, 0xc4, 0x0b, 0x19,
|
||||
0x08, 0x32, 0xa0, 0x08, 0x1a, 0x0a, 0xf3, 0x7f, 0x0e, 0xc5, 0xe8, 0x03,
|
||||
0xff
|
||||
};
|
||||
|
||||
static const uint8_t g_st7121_cmd_c9[] =
|
||||
{
|
||||
0x00, 0x00, 0x04, 0x08, 0x10, 0x00, 0x1f, 0x01, 0x39, 0x3e, 0x00, 0x78,
|
||||
0x06, 0xe2, 0x02, 0x11, 0x33, 0x01, 0x7a, 0x0d, 0x21, 0xc4, 0x0b, 0x19,
|
||||
0x08, 0x32, 0xa0, 0x08, 0x1a, 0x0a, 0xf3, 0x7f, 0x0e, 0xc5, 0xe8, 0x03,
|
||||
0xff
|
||||
};
|
||||
|
||||
static const uint8_t g_st7121_cmd_60d[] =
|
||||
{
|
||||
0x71, 0x21, 0x00
|
||||
};
|
||||
|
||||
static const uint8_t g_st7121_cmd_35[] =
|
||||
{
|
||||
0x00
|
||||
};
|
||||
|
||||
static const struct st7121_init_cmd_s g_st7121_init[] =
|
||||
{
|
||||
{0x60, g_st7121_cmd_60a, sizeof(g_st7121_cmd_60a), 0},
|
||||
{0x60, g_st7121_cmd_60b, sizeof(g_st7121_cmd_60b), 0},
|
||||
{0x60, g_st7121_cmd_60c, sizeof(g_st7121_cmd_60c), 0},
|
||||
{0x78, g_st7121_cmd_78, sizeof(g_st7121_cmd_78), 0},
|
||||
{0x79, g_st7121_cmd_79, sizeof(g_st7121_cmd_79), 0},
|
||||
{0xa4, g_st7121_cmd_a4, sizeof(g_st7121_cmd_a4), 0},
|
||||
{0xb7, g_st7121_cmd_b7, sizeof(g_st7121_cmd_b7), 0},
|
||||
{0xb0, g_st7121_cmd_b0, sizeof(g_st7121_cmd_b0), 0},
|
||||
{0xbf, g_st7121_cmd_bf, sizeof(g_st7121_cmd_bf), 0},
|
||||
{0xa5, g_st7121_cmd_a5, sizeof(g_st7121_cmd_a5), 0},
|
||||
{0xd7, g_st7121_cmd_d7, sizeof(g_st7121_cmd_d7), 0},
|
||||
{0x90, g_st7121_cmd_90, sizeof(g_st7121_cmd_90), 0},
|
||||
{0xa3, g_st7121_cmd_a3, sizeof(g_st7121_cmd_a3), 0},
|
||||
{0xa6, g_st7121_cmd_a6, sizeof(g_st7121_cmd_a6), 0},
|
||||
{0xa7, g_st7121_cmd_a7, sizeof(g_st7121_cmd_a7), 0},
|
||||
{0xac, g_st7121_cmd_ac, sizeof(g_st7121_cmd_ac), 0},
|
||||
{0xad, g_st7121_cmd_ad, sizeof(g_st7121_cmd_ad), 0},
|
||||
{0xae, g_st7121_cmd_ae, sizeof(g_st7121_cmd_ae), 0},
|
||||
{0xb2, g_st7121_cmd_b2, sizeof(g_st7121_cmd_b2), 0},
|
||||
{0xe8, g_st7121_cmd_e8, sizeof(g_st7121_cmd_e8), 0},
|
||||
{0x75, g_st7121_cmd_75, sizeof(g_st7121_cmd_75), 0},
|
||||
{0xe7, g_st7121_cmd_e7, sizeof(g_st7121_cmd_e7), 0},
|
||||
{0xe1, g_st7121_cmd_e1, sizeof(g_st7121_cmd_e1), 0},
|
||||
{0xea, g_st7121_cmd_ea, sizeof(g_st7121_cmd_ea), 0},
|
||||
{0xc8, g_st7121_cmd_c8, sizeof(g_st7121_cmd_c8), 0},
|
||||
{0xc9, g_st7121_cmd_c9, sizeof(g_st7121_cmd_c9), 0},
|
||||
{0x60, g_st7121_cmd_60d, sizeof(g_st7121_cmd_60d), 0},
|
||||
{0x11, NULL, 0, 80},
|
||||
{0x29, NULL, 0, 800},
|
||||
{0x35, g_st7121_cmd_35, sizeof(g_st7121_cmd_35), 0},
|
||||
};
|
||||
|
||||
#define ST7121_INIT_COUNT (sizeof(g_st7121_init) / sizeof(g_st7121_init[0]))
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: st7121_send_init
|
||||
****************************************************************************/
|
||||
|
||||
static int st7121_send_init(FAR struct mipi_dsi_device *device)
|
||||
{
|
||||
unsigned int i;
|
||||
ssize_t n;
|
||||
|
||||
for (i = 0; i < ST7121_INIT_COUNT; i++)
|
||||
{
|
||||
FAR const struct st7121_init_cmd_s *cmd = &g_st7121_init[i];
|
||||
|
||||
n = mipi_dsi_dcs_write(device, cmd->cmd, cmd->data, cmd->len);
|
||||
if (n < 0)
|
||||
{
|
||||
syslog(LOG_ERR,
|
||||
"ERROR: DCS 0x%02x failed: %zd (cmd %u/%u)\n",
|
||||
cmd->cmd, n, i + 1, ST7121_INIT_COUNT);
|
||||
return (int)n;
|
||||
}
|
||||
|
||||
if (cmd->delay_ms > 0)
|
||||
{
|
||||
up_mdelay(cmd->delay_ms);
|
||||
}
|
||||
|
||||
up_mdelay(ST7121_COMMAND_DELAY_MS);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tab5_st7121_initialize
|
||||
****************************************************************************/
|
||||
|
||||
FAR struct mipi_dsi_device *tab5_st7121_initialize(
|
||||
FAR struct mipi_dsi_host *host)
|
||||
{
|
||||
FAR struct mipi_dsi_device *device;
|
||||
int ret;
|
||||
|
||||
if (host == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tab5_lcd_backlight(false);
|
||||
|
||||
ret = tab5_lcd_enable(true);
|
||||
if (ret < 0)
|
||||
{
|
||||
syslog(LOG_ERR, "ERROR: LCD_EN enable failed: %d\n", ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
device = mipi_dsi_device_register(host, ST7121_NAME, 0);
|
||||
if (device == NULL)
|
||||
{
|
||||
syslog(LOG_ERR, "ERROR: mipi_dsi_device_register failed\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
device->lanes = TAB5_MIPI_DSI_LANES;
|
||||
device->format = MIPI_DSI_FMT_RGB565;
|
||||
device->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
|
||||
MIPI_DSI_MODE_LPM;
|
||||
device->hs_rate = TAB5_MIPI_DSI_LANE_BITRATE_MBPS * 1000000UL;
|
||||
device->lp_rate = 0;
|
||||
|
||||
ret = mipi_dsi_attach(device);
|
||||
if (ret < 0)
|
||||
{
|
||||
syslog(LOG_ERR, "ERROR: attach failed: %d\n", ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = mipi_dsi_dcs_soft_reset(device);
|
||||
if (ret < 0)
|
||||
{
|
||||
syslog(LOG_ERR, "ERROR: soft reset failed: %d\n", ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
up_mdelay(120);
|
||||
|
||||
ret = st7121_send_init(device);
|
||||
if (ret < 0)
|
||||
{
|
||||
syslog(LOG_ERR, "ERROR: DCS init failed: %d\n", ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return device;
|
||||
}
|
||||
75
boards/risc-v/esp32p4/esp32p4-tab5/src/esp32p4_lcd_st7121.h
Normal file
75
boards/risc-v/esp32p4/esp32p4-tab5/src/esp32p4_lcd_st7121.h
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
/****************************************************************************
|
||||
* boards/risc-v/esp32p4/esp32p4-tab5/src/esp32p4_lcd_st7121.h
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __BOARDS_RISCV_ESP32P4_ESP32P4_TAB5_SRC_ESP32P4_LCD_ST7121_H
|
||||
#define __BOARDS_RISCV_ESP32P4_ESP32P4_TAB5_SRC_ESP32P4_LCD_ST7121_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <nuttx/video/mipi_dsi.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define EXTERN extern "C"
|
||||
extern "C"
|
||||
{
|
||||
#else
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tab5_st7121_initialize
|
||||
*
|
||||
* Description:
|
||||
* Register the ST7121 as a mipi_dsi_device, attach to the Espressif host,
|
||||
* power-cycle LCD_EN (BSP_LCD_RST is NC), issue DCS soft-reset, and send
|
||||
* the M5Stack Tab5 ST7121 vendor DCS initialization table. Does not start
|
||||
* video; board code calls display_on after video_start.
|
||||
*
|
||||
* Input Parameters:
|
||||
* host - Registered MIPI-DSI host (esp_mipi_dsi_host_get())
|
||||
*
|
||||
* Returned Value:
|
||||
* Pointer to the registered device on success; NULL on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
#ifdef CONFIG_ESP32P4_TAB5_LCD_ST7121
|
||||
FAR struct mipi_dsi_device *tab5_st7121_initialize(
|
||||
FAR struct mipi_dsi_host *host);
|
||||
#endif
|
||||
|
||||
#undef EXTERN
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
#endif /* __BOARDS_RISCV_ESP32P4_ESP32P4_TAB5_SRC_ESP32P4_LCD_ST7121_H */
|
||||
425
boards/risc-v/esp32p4/esp32p4-tab5/src/esp32p4_lcd_st7123.c
Normal file
425
boards/risc-v/esp32p4/esp32p4-tab5/src/esp32p4_lcd_st7123.c
Normal file
|
|
@ -0,0 +1,425 @@
|
|||
/****************************************************************************
|
||||
* boards/risc-v/esp32p4/esp32p4-tab5/src/esp32p4_lcd_st7123.c
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/* ST7123 panel bring-up for M5Stack Tab5.
|
||||
*
|
||||
* Init init table sourced from https://github.com/espressif/esp-iot-solution
|
||||
* under components/display/lcd/esp_lcd_st7123/esp_lcd_st7123.c.
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <syslog.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/video/mipi_dsi.h>
|
||||
|
||||
#include <arch/board/board.h>
|
||||
|
||||
#include "esp32p4-tab5.h"
|
||||
#include "esp32p4_lcd_st7123.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define ST7123_NAME "st7123"
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
struct st7123_init_cmd_s
|
||||
{
|
||||
uint8_t cmd;
|
||||
FAR const uint8_t *data;
|
||||
uint8_t len;
|
||||
uint16_t delay_ms;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/* ESP-BSP Tab5 ST7123 vendor table (disp_init_data_st7123). */
|
||||
|
||||
static const uint8_t g_st7123_cmd_60a[] =
|
||||
{
|
||||
0x71, 0x23, 0xa2
|
||||
};
|
||||
|
||||
static const uint8_t g_st7123_cmd_60b[] =
|
||||
{
|
||||
0x71, 0x23, 0xa3
|
||||
};
|
||||
|
||||
static const uint8_t g_st7123_cmd_60c[] =
|
||||
{
|
||||
0x71, 0x23, 0xa4
|
||||
};
|
||||
|
||||
static const uint8_t g_st7123_cmd_a4[] =
|
||||
{
|
||||
0x31
|
||||
};
|
||||
|
||||
static const uint8_t g_st7123_cmd_d7[] =
|
||||
{
|
||||
0x10, 0x0a, 0x10, 0x2a, 0x80, 0x80
|
||||
};
|
||||
|
||||
static const uint8_t g_st7123_cmd_90[] =
|
||||
{
|
||||
0x71, 0x23, 0x5a, 0x20, 0x24, 0x09, 0x09
|
||||
};
|
||||
|
||||
static const uint8_t g_st7123_cmd_a3[] =
|
||||
{
|
||||
0x80, 0x01, 0x88, 0x30, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x00,
|
||||
0x00, 0x1e, 0x5c, 0x1e, 0x80, 0x00, 0x4f, 0x05, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x46, 0x00, 0x00, 0x1e, 0x5c, 0x1e, 0x80, 0x00, 0x6f, 0x58, 0x00,
|
||||
0x00, 0x00, 0xff
|
||||
};
|
||||
|
||||
static const uint8_t g_st7123_cmd_a6[] =
|
||||
{
|
||||
0x03, 0x00, 0x24, 0x55, 0x36, 0x00, 0x39, 0x00, 0x6e, 0x6e, 0x91, 0xff,
|
||||
0x00, 0x24, 0x55, 0x38, 0x00, 0x37, 0x00, 0x6e, 0x6e, 0x91, 0xff, 0x00,
|
||||
0x24, 0x11, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x6e, 0x91, 0xff, 0x00, 0xec,
|
||||
0x11, 0x00, 0x03, 0x00, 0x03, 0x6e, 0x6e, 0xff, 0xff, 0x00, 0x08, 0x80,
|
||||
0x08, 0x80, 0x06, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
static const uint8_t g_st7123_cmd_a7[] =
|
||||
{
|
||||
0x19, 0x19, 0x80, 0x64, 0x40, 0x07, 0x16, 0x40, 0x00, 0x44, 0x03, 0x6e,
|
||||
0x6e, 0x91, 0xff, 0x08, 0x80, 0x64, 0x40, 0x25, 0x34, 0x40, 0x00, 0x02,
|
||||
0x01, 0x6e, 0x6e, 0x91, 0xff, 0x08, 0x80, 0x64, 0x40, 0x00, 0x00, 0x40,
|
||||
0x00, 0x00, 0x00, 0x6e, 0x6e, 0x91, 0xff, 0x08, 0x80, 0x64, 0x40, 0x00,
|
||||
0x00, 0x00, 0x00, 0x20, 0x00, 0x6e, 0x6e, 0x84, 0xff, 0x08, 0x80, 0x44
|
||||
};
|
||||
|
||||
static const uint8_t g_st7123_cmd_ac[] =
|
||||
{
|
||||
0x03, 0x19, 0x19, 0x18, 0x18, 0x06, 0x13, 0x13, 0x11, 0x11, 0x08, 0x08,
|
||||
0x0a, 0x0a, 0x1c, 0x1c, 0x07, 0x07, 0x00, 0x00, 0x02, 0x02, 0x01, 0x19,
|
||||
0x19, 0x18, 0x18, 0x06, 0x12, 0x12, 0x10, 0x10, 0x09, 0x09, 0x0b, 0x0b,
|
||||
0x1c, 0x1c, 0x07, 0x07, 0x03, 0x03, 0x01, 0x01
|
||||
};
|
||||
|
||||
static const uint8_t g_st7123_cmd_ad[] =
|
||||
{
|
||||
0xf0, 0x00, 0x46, 0x00, 0x03, 0x50, 0x50, 0xff, 0xff, 0xf0, 0x40, 0x06,
|
||||
0x01, 0x07, 0x42, 0x42, 0xff, 0xff, 0x01, 0x00, 0x00, 0xff, 0xff, 0xff,
|
||||
0xff
|
||||
};
|
||||
|
||||
static const uint8_t g_st7123_cmd_ae[] =
|
||||
{
|
||||
0xfe, 0x3f, 0x3f, 0xfe, 0x3f, 0x3f, 0x00
|
||||
};
|
||||
|
||||
static const uint8_t g_st7123_cmd_b2[] =
|
||||
{
|
||||
0x15, 0x19, 0x05, 0x23, 0x49, 0xaf, 0x03, 0x2e, 0x5c, 0xd2, 0xff, 0x10,
|
||||
0x20, 0xfd, 0x20, 0xc0, 0x00
|
||||
};
|
||||
|
||||
static const uint8_t g_st7123_cmd_e8[] =
|
||||
{
|
||||
0x20, 0x6f, 0x04, 0x97, 0x97, 0x3e, 0x04, 0xdc, 0xdc, 0x3e, 0x06, 0xfa,
|
||||
0x26, 0x3e
|
||||
};
|
||||
|
||||
static const uint8_t g_st7123_cmd_75[] =
|
||||
{
|
||||
0x03, 0x04
|
||||
};
|
||||
|
||||
static const uint8_t g_st7123_cmd_e7[] =
|
||||
{
|
||||
0x3b, 0x00, 0x00, 0x7c, 0xa1, 0x8c, 0x20, 0x1a, 0xf0, 0xb1, 0x50, 0x00,
|
||||
0x50, 0xb1, 0x50, 0xb1, 0x50, 0xd8, 0x00, 0x55, 0x00, 0xb1, 0x00, 0x45,
|
||||
0xc9, 0x6a, 0xff, 0x5a, 0xd8, 0x18, 0x88, 0x15, 0xb1, 0x01, 0x01, 0x77
|
||||
};
|
||||
|
||||
static const uint8_t g_st7123_cmd_ea[] =
|
||||
{
|
||||
0x13, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x2c
|
||||
};
|
||||
|
||||
static const uint8_t g_st7123_cmd_b0[] =
|
||||
{
|
||||
0x22, 0x43, 0x11, 0x61, 0x25, 0x43, 0x43
|
||||
};
|
||||
|
||||
static const uint8_t g_st7123_cmd_b7[] =
|
||||
{
|
||||
0x00, 0x00, 0x73, 0x73
|
||||
};
|
||||
|
||||
static const uint8_t g_st7123_cmd_bf[] =
|
||||
{
|
||||
0xa6, 0xaa
|
||||
};
|
||||
|
||||
static const uint8_t g_st7123_cmd_a9[] =
|
||||
{
|
||||
0x00, 0x00, 0x73, 0xff, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03
|
||||
};
|
||||
|
||||
static const uint8_t g_st7123_cmd_c8[] =
|
||||
{
|
||||
0x00, 0x00, 0x10, 0x1f, 0x36, 0x00, 0x5d, 0x04, 0x9d, 0x05, 0x10, 0xf2,
|
||||
0x06, 0x60, 0x03, 0x11, 0xad, 0x00, 0xef, 0x01, 0x22, 0x2e, 0x0e, 0x74,
|
||||
0x08, 0x32, 0xdc, 0x09, 0x33, 0x0f, 0xf3, 0x77, 0x0d, 0xb0, 0xdc, 0x03,
|
||||
0xff
|
||||
};
|
||||
|
||||
static const uint8_t g_st7123_cmd_c9[] =
|
||||
{
|
||||
0x00, 0x00, 0x10, 0x1f, 0x36, 0x00, 0x5d, 0x04, 0x9d, 0x05, 0x10, 0xf2,
|
||||
0x06, 0x60, 0x03, 0x11, 0xad, 0x00, 0xef, 0x01, 0x22, 0x2e, 0x0e, 0x74,
|
||||
0x08, 0x32, 0xdc, 0x09, 0x33, 0x0f, 0xf3, 0x77, 0x0d, 0xb0, 0xdc, 0x03,
|
||||
0xff
|
||||
};
|
||||
|
||||
static const uint8_t g_st7123_cmd_36[] =
|
||||
{
|
||||
0x03
|
||||
};
|
||||
|
||||
static const uint8_t g_st7123_cmd_35[] =
|
||||
{
|
||||
0x00
|
||||
};
|
||||
|
||||
static const struct st7123_init_cmd_s g_st7123_init[] =
|
||||
{
|
||||
{
|
||||
0x60, g_st7123_cmd_60a, sizeof(g_st7123_cmd_60a), 0
|
||||
},
|
||||
{
|
||||
0x60, g_st7123_cmd_60b, sizeof(g_st7123_cmd_60b), 0
|
||||
},
|
||||
{
|
||||
0x60, g_st7123_cmd_60c, sizeof(g_st7123_cmd_60c), 0
|
||||
},
|
||||
{
|
||||
0xa4, g_st7123_cmd_a4, sizeof(g_st7123_cmd_a4), 0
|
||||
},
|
||||
{
|
||||
0xd7, g_st7123_cmd_d7, sizeof(g_st7123_cmd_d7), 0
|
||||
},
|
||||
{
|
||||
0x90, g_st7123_cmd_90, sizeof(g_st7123_cmd_90), 0
|
||||
},
|
||||
{
|
||||
0xa3, g_st7123_cmd_a3, sizeof(g_st7123_cmd_a3), 0
|
||||
},
|
||||
{
|
||||
0xa6, g_st7123_cmd_a6, sizeof(g_st7123_cmd_a6), 0
|
||||
},
|
||||
{
|
||||
0xa7, g_st7123_cmd_a7, sizeof(g_st7123_cmd_a7), 0
|
||||
},
|
||||
{
|
||||
0xac, g_st7123_cmd_ac, sizeof(g_st7123_cmd_ac), 0
|
||||
},
|
||||
{
|
||||
0xad, g_st7123_cmd_ad, sizeof(g_st7123_cmd_ad), 0
|
||||
},
|
||||
{
|
||||
0xae, g_st7123_cmd_ae, sizeof(g_st7123_cmd_ae), 0
|
||||
},
|
||||
{
|
||||
0xb2, g_st7123_cmd_b2, sizeof(g_st7123_cmd_b2), 0
|
||||
},
|
||||
{
|
||||
0xe8, g_st7123_cmd_e8, sizeof(g_st7123_cmd_e8), 0
|
||||
},
|
||||
{
|
||||
0x75, g_st7123_cmd_75, sizeof(g_st7123_cmd_75), 0
|
||||
},
|
||||
{
|
||||
0xe7, g_st7123_cmd_e7, sizeof(g_st7123_cmd_e7), 0
|
||||
},
|
||||
{
|
||||
0xea, g_st7123_cmd_ea, sizeof(g_st7123_cmd_ea), 0
|
||||
},
|
||||
{
|
||||
0xb0, g_st7123_cmd_b0, sizeof(g_st7123_cmd_b0), 0
|
||||
},
|
||||
{
|
||||
0xb7, g_st7123_cmd_b7, sizeof(g_st7123_cmd_b7), 0
|
||||
},
|
||||
{
|
||||
0xbf, g_st7123_cmd_bf, sizeof(g_st7123_cmd_bf), 0
|
||||
},
|
||||
{
|
||||
0xa9, g_st7123_cmd_a9, sizeof(g_st7123_cmd_a9), 0
|
||||
},
|
||||
{
|
||||
0xc8, g_st7123_cmd_c8, sizeof(g_st7123_cmd_c8), 0
|
||||
},
|
||||
{
|
||||
0xc9, g_st7123_cmd_c9, sizeof(g_st7123_cmd_c9), 0
|
||||
},
|
||||
{
|
||||
0x36, g_st7123_cmd_36, sizeof(g_st7123_cmd_36), 0
|
||||
},
|
||||
|
||||
/* 0x11 / 0x29: 0-param DCS (dummy 0x00 as 1-param broke sleep-out).
|
||||
* Delays match ESP-BSP disp_init_data_st7123 (120 / 50).
|
||||
*/
|
||||
|
||||
{
|
||||
0x11, NULL, 0, 120
|
||||
},
|
||||
{
|
||||
0x29, NULL, 0, 50
|
||||
},
|
||||
{
|
||||
0x35, g_st7123_cmd_35, sizeof(g_st7123_cmd_35), 0
|
||||
},
|
||||
};
|
||||
|
||||
#define ST7123_INIT_COUNT (sizeof(g_st7123_init) / sizeof(g_st7123_init[0]))
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: st7123_send_init
|
||||
*
|
||||
* Description:
|
||||
* Send the ST7123 vendor init table.
|
||||
*
|
||||
* Input Parameters:
|
||||
* device - Pointer to the MIPI-DSI device structure.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero on success, -1 on failure.
|
||||
****************************************************************************/
|
||||
|
||||
static int st7123_send_init(FAR struct mipi_dsi_device *device)
|
||||
{
|
||||
unsigned int i;
|
||||
ssize_t n;
|
||||
|
||||
for (i = 0; i < ST7123_INIT_COUNT; i++)
|
||||
{
|
||||
FAR const struct st7123_init_cmd_s *cmd = &g_st7123_init[i];
|
||||
|
||||
n = mipi_dsi_dcs_write(device, cmd->cmd, cmd->data, cmd->len);
|
||||
if (n < 0)
|
||||
{
|
||||
syslog(LOG_ERR,
|
||||
"ERROR: DCS 0x%02x failed: %zd (cmd %u/%u)\n",
|
||||
cmd->cmd, n, i + 1, ST7123_INIT_COUNT);
|
||||
return (int)n;
|
||||
}
|
||||
|
||||
if (cmd->delay_ms > 0)
|
||||
{
|
||||
up_mdelay(cmd->delay_ms);
|
||||
}
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tab5_st7123_initialize
|
||||
*
|
||||
* Description:
|
||||
* Register the ST7123 as a mipi_dsi_device, attach to the Espressif host,
|
||||
* pulse LCD reset via PI4IOE, and send the ESP-BSP Tab5 vendor DCS init
|
||||
* table (disp_init_data_st7123[]). Does not start video; board code
|
||||
* calls display_on after video_start.
|
||||
*
|
||||
* Input Parameters:
|
||||
* host - Pointer to the MIPI-DSI host structure.
|
||||
*
|
||||
* Returned Value:
|
||||
* Pointer to the MIPI-DSI device structure on success, NULL on failure.
|
||||
****************************************************************************/
|
||||
|
||||
FAR struct mipi_dsi_device *tab5_st7123_initialize(
|
||||
FAR struct mipi_dsi_host *host)
|
||||
{
|
||||
FAR struct mipi_dsi_device *device;
|
||||
int ret;
|
||||
|
||||
if (host == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = tab5_lcd_enable(true);
|
||||
if (ret < 0)
|
||||
{
|
||||
syslog(LOG_ERR, "ERROR: LCD_EN enable failed: %d\n", ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
device = mipi_dsi_device_register(host, ST7123_NAME, 0);
|
||||
if (device == NULL)
|
||||
{
|
||||
syslog(LOG_ERR, "ERROR: mipi_dsi_device_register failed\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
device->lanes = TAB5_MIPI_DSI_LANES;
|
||||
device->format = MIPI_DSI_FMT_RGB565;
|
||||
device->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
|
||||
MIPI_DSI_MODE_LPM;
|
||||
device->hs_rate = TAB5_MIPI_DSI_LANE_BITRATE_MBPS * 1000000UL;
|
||||
device->lp_rate = 0;
|
||||
|
||||
ret = mipi_dsi_attach(device);
|
||||
if (ret < 0)
|
||||
{
|
||||
syslog(LOG_ERR, "ERROR: attach failed: %d\n", ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = st7123_send_init(device);
|
||||
if (ret < 0)
|
||||
{
|
||||
syslog(LOG_ERR, "ERROR: DCS init failed: %d\n", ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return device;
|
||||
}
|
||||
74
boards/risc-v/esp32p4/esp32p4-tab5/src/esp32p4_lcd_st7123.h
Normal file
74
boards/risc-v/esp32p4/esp32p4-tab5/src/esp32p4_lcd_st7123.h
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
/****************************************************************************
|
||||
* boards/risc-v/esp32p4/esp32p4-tab5/src/esp32p4_lcd_st7123.h
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __BOARDS_RISCV_ESP32P4_ESP32P4_TAB5_SRC_ESP32P4_LCD_ST7123_H
|
||||
#define __BOARDS_RISCV_ESP32P4_ESP32P4_TAB5_SRC_ESP32P4_LCD_ST7123_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <nuttx/video/mipi_dsi.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define EXTERN extern "C"
|
||||
extern "C"
|
||||
{
|
||||
#else
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tab5_st7123_initialize
|
||||
*
|
||||
* Description:
|
||||
* Register the ST7123 as a mipi_dsi_device, attach to the Espressif host,
|
||||
* pulse LCD reset via PI4IOE, and send the ESP-BSP Tab5 vendor DCS init
|
||||
* table (disp_init_data_st7123[]). Does not start video; board code
|
||||
* calls display_on after video_start.
|
||||
*
|
||||
* Input Parameters:
|
||||
* host - Registered MIPI-DSI host (esp_mipi_dsi_host_get())
|
||||
*
|
||||
* Returned Value:
|
||||
* Pointer to the registered device on success; NULL on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
#ifdef CONFIG_ESP32P4_TAB5_LCD_ST7123
|
||||
FAR struct mipi_dsi_device *tab5_st7123_initialize(
|
||||
FAR struct mipi_dsi_host *host);
|
||||
#endif
|
||||
#undef EXTERN
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
#endif /* __BOARDS_RISCV_ESP32P4_ESP32P4_TAB5_SRC_ESP32P4_LCD_ST7123_H */
|
||||
69
boards/risc-v/esp32p4/esp32p4-tab5/src/esp32p4_mipi_dpi.c
Normal file
69
boards/risc-v/esp32p4/esp32p4-tab5/src/esp32p4_mipi_dpi.c
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
/****************************************************************************
|
||||
* boards/risc-v/esp32p4/esp32p4-tab5/src/esp32p4_mipi_dpi.c
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <nuttx/video/mipi_dsi.h>
|
||||
|
||||
#include <arch/board/board.h>
|
||||
|
||||
#include "esp32p4-tab5.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tab5_mipi_dsi_dpi_config
|
||||
*
|
||||
* Description:
|
||||
* Configure the MIPI-DSI DPI configuration.
|
||||
*
|
||||
* Input Parameters:
|
||||
* cfg - Pointer to the MIPI-DSI DPI configuration structure.
|
||||
*
|
||||
* Returned Value:
|
||||
* None.
|
||||
****************************************************************************/
|
||||
|
||||
void tab5_mipi_dsi_dpi_config(FAR struct esp_mipi_dsi_dpi_config_s *cfg)
|
||||
{
|
||||
DEBUGASSERT(cfg != NULL);
|
||||
|
||||
cfg->h_res = TAB5_MIPI_DSI_H_RES;
|
||||
cfg->v_res = TAB5_MIPI_DSI_V_RES;
|
||||
cfg->hsync_pulse_width = TAB5_MIPI_DSI_HSYNC_PULSE_WIDTH;
|
||||
cfg->hsync_back_porch = TAB5_MIPI_DSI_HSYNC_BACK_PORCH;
|
||||
cfg->hsync_front_porch = TAB5_MIPI_DSI_HSYNC_FRONT_PORCH;
|
||||
cfg->vsync_pulse_width = TAB5_MIPI_DSI_VSYNC_PULSE_WIDTH;
|
||||
cfg->vsync_back_porch = TAB5_MIPI_DSI_VSYNC_BACK_PORCH;
|
||||
cfg->vsync_front_porch = TAB5_MIPI_DSI_VSYNC_FRONT_PORCH;
|
||||
cfg->dpi_clock_freq_mhz = TAB5_MIPI_DSI_DPI_CLK_MHZ;
|
||||
cfg->virtual_channel = 0;
|
||||
cfg->format = MIPI_DSI_FMT_RGB565;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue