openmv/lib/alif/components/Source/ILI9488_LCD_panel.c
iabdalkader daf2bb30da misc: Restructure repo.
Signed-off-by: iabdalkader <i.abdalkader@gmail.com>
2025-04-13 08:28:34 +02:00

335 lines
8.5 KiB
C

/* Copyright (C) 2024 Alif Semiconductor - All Rights Reserved.
* Use, distribution and modification of this code is permitted under the
* terms stated in the Alif Semiconductor Software License Agreement
*
* You should have received a copy of the Alif Semiconductor Software
* License Agreement with this file. If not, please write to:
* contact@alifsemi.com, or visit: https://alifsemi.com/license
*
*/
/* System Includes */
#include "RTE_Device.h"
#include "RTE_Components.h"
#include CMSIS_device_header
#if RTE_MIPI_DSI_ILI9488_PANEL
#include "DSI_DCS.h"
#include "Driver_GPIO.h"
#include "display.h"
/* ILI9488 panel reset GPIO port */
extern ARM_DRIVER_GPIO ARM_Driver_GPIO_(RTE_ILI9488_PANEL_RESET_GPIO_PORT);
static ARM_DRIVER_GPIO *GPIO_Driver_Rst = &ARM_Driver_GPIO_(RTE_ILI9488_PANEL_RESET_GPIO_PORT);
/* ILI9488 panel black light LED GPIO port */
extern ARM_DRIVER_GPIO ARM_Driver_GPIO_(RTE_ILI9488_PANEL_BL_LED_GPIO_PORT);
static ARM_DRIVER_GPIO *GPIO_Driver_BLED = &ARM_Driver_GPIO_(RTE_ILI9488_PANEL_BL_LED_GPIO_PORT);
#define ILI9488_PANEL_MIPI_DATA_LANES 1
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
/* Panel long packet configurations */
uint8_t pgam_ctrl[] = {0xE0,0x00,0x10,0x14,0x01,0x0E,0x04,0x33,0x56,0x48,0x03,0x0C,0x0B,0x2B,0x34,0x0F};
uint8_t ngam_ctrl[] = {0xE1,0x00,0x12,0x18,0x05,0x12,0x06,0x40,0x34,0x57,0x06,0x10,0x0C,0x3B,0x3F,0x0F};
uint8_t power_ctrl1[] = {0xC0,0x0F,0x0C};
uint8_t vcom_ctrl[] = {0xC5,0x00,0x25,0x80};
uint8_t display_func_ctrl[] = {0xB6,0x02,0x02};
uint8_t adjust_ctrl[] = {0xF7,0xA9,0x51,0x2C,0x82};
/**
\fn int32_t ILI9488_Display_Reset (void)
\brief Reset ILI9488 Display Panel
\param[in] none
\return \ref execution_status
*/
static int32_t ILI9488_Display_Reset (void)
{
int32_t ret = 0;
if(GPIO_Driver_Rst == NULL)
{
return ARM_DRIVER_ERROR_PARAMETER;
}
ret = GPIO_Driver_Rst->Initialize(RTE_ILI9488_PANEL_RESET_PIN_NO, NULL);
if(ret != ARM_DRIVER_OK)
{
return ARM_DRIVER_ERROR;
}
ret = GPIO_Driver_Rst->PowerControl(RTE_ILI9488_PANEL_RESET_PIN_NO,
ARM_POWER_FULL);
if(ret != ARM_DRIVER_OK)
{
return ARM_DRIVER_ERROR;
}
ret = GPIO_Driver_Rst->SetDirection(RTE_ILI9488_PANEL_RESET_PIN_NO,
GPIO_PIN_DIRECTION_OUTPUT);
if(ret != ARM_DRIVER_OK)
{
return ARM_DRIVER_ERROR;
}
ret = GPIO_Driver_Rst->SetValue(RTE_ILI9488_PANEL_RESET_PIN_NO,
GPIO_PIN_OUTPUT_STATE_HIGH);
if(ret != ARM_DRIVER_OK)
{
return ARM_DRIVER_ERROR;
}
sys_busy_loop_us(5000);
ret = GPIO_Driver_Rst->SetValue(RTE_ILI9488_PANEL_RESET_PIN_NO,
GPIO_PIN_OUTPUT_STATE_LOW);
if(ret != ARM_DRIVER_OK)
{
return ARM_DRIVER_ERROR;
}
sys_busy_loop_us(20000);
ret = GPIO_Driver_Rst->SetValue(RTE_ILI9488_PANEL_RESET_PIN_NO,
GPIO_PIN_OUTPUT_STATE_HIGH);
if(ret != ARM_DRIVER_OK)
{
return ARM_DRIVER_ERROR;
}
sys_busy_loop_us(100000);
sys_busy_loop_us(50000);
return ARM_DRIVER_OK;
}
/**
\fn int32_t ILI9488_BL_LED_Init (void)
\brief Initialize GPIO for BL LED of ILI9488 Display Panel.
\return \ref execution_status
*/
static int32_t ILI9488_BL_LED_Init(void)
{
int32_t ret = 0;
if(GPIO_Driver_BLED == NULL)
{
return ARM_DRIVER_ERROR_PARAMETER;
}
ret = GPIO_Driver_BLED->Initialize(RTE_ILI9488_PANEL_BL_LED_PIN_NO, NULL);
if(ret != ARM_DRIVER_OK)
{
return ARM_DRIVER_ERROR;
}
ret = GPIO_Driver_BLED->PowerControl(RTE_ILI9488_PANEL_BL_LED_PIN_NO,
ARM_POWER_FULL);
if(ret != ARM_DRIVER_OK)
{
return ARM_DRIVER_ERROR;
}
return GPIO_Driver_BLED->SetDirection(RTE_ILI9488_PANEL_BL_LED_PIN_NO,
GPIO_PIN_DIRECTION_OUTPUT);
}
/**
\fn int32_t ILI9488_BL_LED_Control (uint8_t state)
\brief Control BL LED of ILI9488 Display Panel.
\param[in] state ENABLE/DISABLE
\return \ref execution_status
*/
static int32_t ILI9488_BL_LED_Control(uint8_t state)
{
int32_t ret = 0;
if(state == ENABLE)
{
ret = GPIO_Driver_BLED->SetValue(RTE_ILI9488_PANEL_BL_LED_PIN_NO,
GPIO_PIN_OUTPUT_STATE_HIGH);
if(ret != ARM_DRIVER_OK)
{
return ARM_DRIVER_ERROR;
}
}
else
{
ret = GPIO_Driver_BLED->SetValue(RTE_ILI9488_PANEL_BL_LED_PIN_NO,
GPIO_PIN_OUTPUT_STATE_LOW);
if(ret != ARM_DRIVER_OK)
{
return ARM_DRIVER_ERROR;
}
}
return ARM_DRIVER_OK;
}
/**
\fn void ILI9488_Configure (void)
\brief Configure ILI9488 Display Panel
*/
static void ILI9488_Configure(void)
{
DSI_DCS_Long_Write(pgam_ctrl, ARRAY_SIZE(pgam_ctrl));
sys_busy_loop_us(10);
DSI_DCS_Long_Write(ngam_ctrl, ARRAY_SIZE(ngam_ctrl));
sys_busy_loop_us(10);
DSI_DCS_Long_Write(power_ctrl1, ARRAY_SIZE(power_ctrl1));
sys_busy_loop_us(10);
DSI_DCS_Short_Write(0xC1, 0x41);
sys_busy_loop_us(10);
DSI_DCS_Long_Write(vcom_ctrl, ARRAY_SIZE(vcom_ctrl));
DSI_DCS_Short_Write(0x36, 0x48);
DSI_DCS_Short_Write(0x3A, 0x55);
DSI_DCS_Short_Write(0xB0, 0x00);
DSI_DCS_Short_Write(0xB1, 0xA0);
DSI_DCS_Short_Write(0xB4, 0x02);
DSI_DCS_Long_Write(display_func_ctrl, ARRAY_SIZE(display_func_ctrl));
DSI_DCS_Short_Write(0xE9, 0x00);
DSI_DCS_Long_Write(adjust_ctrl, ARRAY_SIZE(adjust_ctrl));
DSI_DCS_CMD_Short_Write(0x21);
DSI_DCS_CMD_Short_Write(0x11);
sys_busy_loop_us(100000);
sys_busy_loop_us(20000);
DSI_DCS_CMD_Short_Write(0x29);
sys_busy_loop_us(20000);
}
/**
\fn int32_t ILI9488_Init(void)
\brief Initialize ILI9488 Display Panel
\return \ref execution_status
*/
static int32_t ILI9488_Init(void)
{
int32_t ret = ARM_DRIVER_OK;
ret = ILI9488_Display_Reset();
if(ret != ARM_DRIVER_OK)
{
return ret;
}
return ILI9488_BL_LED_Init();
}
/**
\fn int32_t ILI9488_Uninit(void)
\brief Un-Initialize ILI9488 Display Panel
\return \ref execution_status
*/
static int32_t ILI9488_Uninit(void)
{
return GPIO_Driver_Rst->SetValue(RTE_ILI9488_PANEL_RESET_PIN_NO,
GPIO_PIN_OUTPUT_STATE_LOW);
}
/**
\fn int32_t ILI9488_Control(uint32_t control)
\brief Control ILI9488 Display Panel
\return \ref execution_status
*/
static int32_t ILI9488_Control(uint32_t control)
{
switch(control)
{
case DISPALY_PANEL_CONFIG:
{
ILI9488_Configure();
break;
}
default:
{
return ARM_DRIVER_ERROR_UNSUPPORTED;
}
}
return ARM_DRIVER_OK;
}
/**
\fn int32_t ILI9488_start(void)
\brief start ILI9488 Display Panel
\return \ref execution_status
*/
static int32_t ILI9488_Start(void)
{
return ILI9488_BL_LED_Control(ENABLE);
}
/**
\fn int32_t ILI9488_stop(void)
\brief stop ILI9488 Display Panel
\return \ref execution_status
*/
static int32_t ILI9488_Stop(void)
{
return ILI9488_BL_LED_Control(DISABLE);
}
static DISPLAY_PANEL_OPERATIONS ILI9488_display_ops =
{
.Init = ILI9488_Init,
.Uninit = ILI9488_Uninit,
.Control = ILI9488_Control,
.Start = ILI9488_Start,
.Stop = ILI9488_Stop
};
static DSI_INFO ILI9488_dsi_info =
{
.max_bitrate = RTE_ILI9488_PANEL_MAX_BITRATE_MBPS,
.n_lanes = ILI9488_PANEL_MIPI_DATA_LANES,
.vc_id = RTE_ILI9488_PANEL_DSI_VC_ID,
.color_coding = RTE_ILI9488_PANEL_DSI_COLOR_MODE,
};
static DISPLAY_PANEL_DEVICE ILI9488_display_panel =
{
.hsync_time = RTE_ILI9488_PANEL_HSYNC_TIME,
.hbp_time = RTE_ILI9488_PANEL_HBP_TIME,
.hfp_time = RTE_ILI9488_PANEL_HFP_TIME,
.hactive_time = RTE_ILI9488_PANEL_HACTIVE_TIME,
.vsync_line = RTE_ILI9488_PANEL_VSYNC_LINE,
.vbp_line = RTE_ILI9488_PANEL_VBP_LINE,
.vfp_line = RTE_ILI9488_PANEL_VFP_LINE,
.vactive_line = RTE_ILI9488_PANEL_VACTIVE_LINE,
.dsi_info = &ILI9488_dsi_info,
.ops = &ILI9488_display_ops,
};
/* Registering Display Panel */
DISPLAY_PANEL(ILI9488_display_panel)
#endif