Files
admin dac37fd077
Make sure docs are updated / settings_md (push) Canceled after 0s
Build firmware / test (push) Canceled after 0s
Build firmware / build-SITL-Windows (push) Canceled after 0s
Build firmware / build-SITL-Mac (push) Canceled after 0s
Build firmware / build-SITL-Linux (push) Canceled after 0s
Build firmware / build-SITL-Linux-arm64 (push) Canceled after 0s
Build firmware / upload-artifacts (push) Canceled after 0s
Build firmware / build-single-target (push) Canceled after 0s
Build firmware / build (9) (push) Canceled after 0s
Build firmware / build (8) (push) Canceled after 0s
Build firmware / build (7) (push) Canceled after 0s
Build firmware / build (6) (push) Canceled after 0s
Build firmware / build (5) (push) Canceled after 0s
Build firmware / build (4) (push) Canceled after 0s
Build firmware / build (3) (push) Canceled after 0s
Build firmware / build (2) (push) Canceled after 0s
Build firmware / build (14) (push) Canceled after 0s
Build firmware / build (13) (push) Canceled after 0s
Build firmware / build (12) (push) Canceled after 0s
Build firmware / build (11) (push) Canceled after 0s
Build firmware / build (10) (push) Canceled after 0s
Build firmware / build (1) (push) Canceled after 0s
Build firmware / build (0) (push) Canceled after 0s
Build firmware / detect (push) Canceled after 0s
Build pre-release / build (push) Canceled after 0s
Build pre-release / Release (push) Canceled after 0s
Sync inav to Gitea
2026-08-03 16:37:40 +08:00

866 lines
29 KiB
C

/**
******************************************************************************
* @file otm8009a.c
* @author MCD Application Team
* @brief This file provides the LCD Driver for KoD KM-040TMP-02-0621 (WVGA)
* DSI LCD Display OTM8009A.
******************************************************************************
* @attention
*
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "otm8009a.h"
#include <stddef.h>
/** @addtogroup BSP
* @{
*/
/** @addtogroup Components
* @{
*/
/** @defgroup OTM8009A OTM8009A
* @brief This file provides a set of functions needed to drive the
* otm8009a IC display driver.
* @{
*/
/** @defgroup OTM8009A_Exported_Types OTM8009A Exported Types
* @{
*/
OTM8009A_LCD_Drv_t OTM8009A_LCD_Driver =
{
OTM8009A_Init,
OTM8009A_DeInit,
OTM8009A_ReadID,
OTM8009A_DisplayOn,
OTM8009A_DisplayOff,
OTM8009A_SetBrightness,
OTM8009A_GetBrightness,
OTM8009A_SetOrientation,
OTM8009A_GetOrientation,
OTM8009A_SetCursor,
OTM8009A_DrawBitmap,
OTM8009A_FillRGBRect,
OTM8009A_DrawHLine,
OTM8009A_DrawVLine,
OTM8009A_FillRect,
OTM8009A_GetPixel,
OTM8009A_SetPixel,
OTM8009A_GetXSize,
OTM8009A_GetYSize,
};
static OTM8009A_LCD_Ctx_t OTM8009ACtx;
/**
* @}
*/
/** @defgroup OTM8009A_Private_Constants OTM8009A Private Constants
* @{
*/
/*
* @brief Constant tables of register settings used to transmit DSI
* command packets as power up initialization sequence of the KoD LCD (OTM8009A LCD Driver)
*/
/*
* CASET value (Column Address Set) : X direction LCD GRAM boundaries
* depending on LCD orientation mode and PASET value (Page Address Set) : Y direction
* LCD GRAM boundaries depending on LCD orientation mode
* XS[15:0] = 0x000 = 0, XE[15:0] = 0x31F = 799 for landscape mode : apply to CASET
* YS[15:0] = 0x000 = 0, YE[15:0] = 0x31F = 799 for portrait mode : apply to PASET
*/
static const uint8_t LcdRegData27[] = {0x00, 0x00, 0x03, 0x1F};
/*
* XS[15:0] = 0x000 = 0, XE[15:0] = 0x1DF = 479 for portrait mode : apply to CASET
* YS[15:0] = 0x000 = 0, YE[15:0] = 0x1DF = 479 for landscape mode : apply to PASET
*/
static const uint8_t LcdRegData28[] = {0x00, 0x00, 0x01, 0xDF};
/**
* @}
*/
/* Private macros ------------------------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/** @defgroup OTM8009A_Private_FunctionsPrototyes OTM8009A Private_Functions Prototyes
* @{
*/
static int32_t OTM8009A_ReadRegWrap(void *Handle, uint16_t Reg, uint8_t* Data, uint16_t Length);
static int32_t OTM8009A_WriteRegWrap(void *Handle, uint16_t Reg, uint8_t *pData, uint16_t Length);
static int32_t OTM8009A_IO_Delay(OTM8009A_Object_t *pObj, uint32_t Delay);
/**
* @}
*/
/** @defgroup OTM8009A_Exported_Variables
* @{
*/
/**
* @}
*/
/* Exported functions ---------------------------------------------------------*/
/** @defgroup OTM8009A_Exported_Functions OTM8009A Exported Functions
* @{
*/
/**
* @brief Register component IO bus
* @param Component object pointer
* @retval Component status
*/
int32_t OTM8009A_RegisterBusIO (OTM8009A_Object_t *pObj, OTM8009A_IO_t *pIO)
{
int32_t ret = OTM8009A_OK;
if(pObj == NULL)
{
ret = OTM8009A_ERROR;
}
else
{
pObj->IO.WriteReg = pIO->WriteReg;
pObj->IO.ReadReg = pIO->ReadReg;
pObj->IO.GetTick = pIO->GetTick;
pObj->Ctx.ReadReg = OTM8009A_ReadRegWrap;
pObj->Ctx.WriteReg = OTM8009A_WriteRegWrap;
pObj->Ctx.handle = pObj;
}
return ret;
}
/**
* @brief Initializes the LCD KoD display part by communication in DSI mode in Video Mode
* with IC Display Driver OTM8009A (see IC Driver specification for more information).
* @param pObj Component object
* @param ColorCoding Color Code
* @param Orientation Display orientation
* @retval Component status
*/
int32_t OTM8009A_Init(OTM8009A_Object_t *pObj, uint32_t ColorCoding, uint32_t Orientation)
{
int32_t ret;
static const uint8_t lcd_reg_data1[] = {0x80,0x09,0x01};
static const uint8_t lcd_reg_data2[] = {0x80,0x09};
static const uint8_t lcd_reg_data3[] = {0x00,0x09,0x0F,0x0E,0x07,0x10,0x0B,0x0A,0x04,0x07,0x0B,0x08,0x0F,0x10,0x0A,0x01};
static const uint8_t lcd_reg_data4[] = {0x00,0x09,0x0F,0x0E,0x07,0x10,0x0B,0x0A,0x04,0x07,0x0B,0x08,0x0F,0x10,0x0A,0x01};
static const uint8_t lcd_reg_data5[] = {0x79,0x79};
static const uint8_t lcd_reg_data6[] = {0x00,0x01};
static const uint8_t lcd_reg_data7[] = {0x85,0x01,0x00,0x84,0x01,0x00};
static const uint8_t lcd_reg_data8[] = {0x18,0x04,0x03,0x39,0x00,0x00,0x00,0x18,0x03,0x03,0x3A,0x00,0x00,0x00};
static const uint8_t lcd_reg_data9[] = {0x18,0x02,0x03,0x3B,0x00,0x00,0x00,0x18,0x01,0x03,0x3C,0x00,0x00,0x00};
static const uint8_t lcd_reg_data10[] = {0x01,0x01,0x20,0x20,0x00,0x00,0x01,0x02,0x00,0x00};
static const uint8_t lcd_reg_data11[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
static const uint8_t lcd_reg_data12[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
static const uint8_t lcd_reg_data13[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
static const uint8_t lcd_reg_data14[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
static const uint8_t lcd_reg_data15[] = {0x00,0x04,0x04,0x04,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
static const uint8_t lcd_reg_data16[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x04,0x04,0x04,0x04,0x00,0x00,0x00,0x00};
static const uint8_t lcd_reg_data17[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
static const uint8_t lcd_reg_data18[] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
static const uint8_t lcd_reg_data19[] = {0x00,0x26,0x09,0x0B,0x01,0x25,0x00,0x00,0x00,0x00};
static const uint8_t lcd_reg_data20[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x26,0x0A,0x0C,0x02};
static const uint8_t lcd_reg_data21[] = {0x25,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
static const uint8_t lcd_reg_data22[] = {0x00,0x25,0x0C,0x0A,0x02,0x26,0x00,0x00,0x00,0x00};
static const uint8_t lcd_reg_data23[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x25,0x0B,0x09,0x01};
static const uint8_t lcd_reg_data24[] = {0x26,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
static const uint8_t lcd_reg_data25[] = {0xFF,0xFF,0xFF};
static const uint8_t short_reg_data[] = {
0x00,0x00,0x80,0x30,0x8A,0x40,0xB1,0xA9,0x91,0x34,0xB4,0x50,0x4E,0x81,0x66,0xA1,0x08,
0x92,0x01,0x95,0x94,0x33,0xA3,0x1B,0x82,0x83,0x83,0x0E,0xA6,0xA0,0xB0,0xC0,0xD0,0x90,
0xE0,0xF0,0x00,OTM8009A_COLMOD_RGB565,OTM8009A_COLMOD_RGB888,0x7F,0x2C,0x02,0xFF,0x00,
0x00,0x00,0x66,0xB6,0x06,0xB1,0x06};
/* Enable CMD2 to access vendor specific commands */
/* Enter in command 2 mode and set EXTC to enable address shift function (0x00) */
ret = otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_NOP, &short_reg_data[1], 0);
ret += otm8009a_write_reg(&pObj->Ctx, 0xFF, lcd_reg_data1, 3);
/* Enter ORISE Command 2 */
/* Shift address to 0x80 */
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_NOP, &short_reg_data[2], 0);
ret += otm8009a_write_reg(&pObj->Ctx, 0xFF, lcd_reg_data2, 2);
/////////////////////////////////////////////////////////////////////
/* SD_PCH_CTRL - 0xC480h - 129th parameter - Default 0x00 */
/* Set SD_PT */
/* -> Source output level during porch and non-display area to GND */
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_NOP, &short_reg_data[2], 0);
ret += otm8009a_write_reg(&pObj->Ctx, 0xC4, &short_reg_data[3], 0);
(void)OTM8009A_IO_Delay(pObj, 10);
/* Not documented */
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_NOP, &short_reg_data[4], 0);
ret += otm8009a_write_reg(&pObj->Ctx, 0xC4, &short_reg_data[5], 0);
(void)OTM8009A_IO_Delay(pObj, 10);
/////////////////////////////////////////////////////////////////////
/* PWR_CTRL4 - 0xC4B0h - 178th parameter - Default 0xA8 */
/* Set gvdd_en_test */
/* -> enable GVDD test mode !!! */
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_NOP, &short_reg_data[6], 0);
ret += otm8009a_write_reg(&pObj->Ctx, 0xC5, &short_reg_data[7], 0);
/* PWR_CTRL2 - 0xC590h - 146th parameter - Default 0x79 */
/* Set pump 4 vgh voltage */
/* -> from 15.0v down to 13.0v */
/* Set pump 5 vgh voltage */
/* -> from -12.0v downto -9.0v */
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_NOP, &short_reg_data[8], 0);
ret += otm8009a_write_reg(&pObj->Ctx, 0xC5, &short_reg_data[9], 0);
/* P_DRV_M - 0xC0B4h - 181th parameter - Default 0x00 */
/* -> Column inversion */
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_NOP, &short_reg_data[10], 0);
ret += otm8009a_write_reg(&pObj->Ctx, 0xC0, &short_reg_data[11], 0);
/* VCOMDC - 0xD900h - 1st parameter - Default 0x39h */
/* VCOM Voltage settings */
/* -> from -1.0000v downto -1.2625v */
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_NOP, &short_reg_data[1], 0);
ret += otm8009a_write_reg(&pObj->Ctx, 0xD9, &short_reg_data[12], 0);
/* Oscillator adjustment for Idle/Normal mode (LPDT only) set to 65Hz (default is 60Hz) */
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_NOP, &short_reg_data[13], 0);
ret += otm8009a_write_reg(&pObj->Ctx, 0xC1, &short_reg_data[14], 0);
/* Video mode internal */
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_NOP, &short_reg_data[15], 0);
ret += otm8009a_write_reg(&pObj->Ctx, 0xC1, &short_reg_data[16], 0);
/* PWR_CTRL2 - 0xC590h - 147h parameter - Default 0x00 */
/* Set pump 4&5 x6 */
/* -> ONLY VALID when PUMP4_EN_ASDM_HV = "0" */
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_NOP, &short_reg_data[17], 0);
ret += otm8009a_write_reg(&pObj->Ctx, 0xC5, &short_reg_data[18], 0);
/* PWR_CTRL2 - 0xC590h - 150th parameter - Default 0x33h */
/* Change pump4 clock ratio */
/* -> from 1 line to 1/2 line */
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_NOP, &short_reg_data[19], 0);
ret += otm8009a_write_reg(&pObj->Ctx, 0xC5, &short_reg_data[9], 0);
/* GVDD/NGVDD settings */
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_NOP, &short_reg_data[1], 0);
ret += otm8009a_write_reg(&pObj->Ctx, 0xD8, lcd_reg_data5, 2);
/* PWR_CTRL2 - 0xC590h - 149th parameter - Default 0x33h */
/* Rewrite the default value ! */
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_NOP, &short_reg_data[20], 0);
ret += otm8009a_write_reg(&pObj->Ctx, 0xC5, &short_reg_data[21], 0);
/* Panel display timing Setting 3 */
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_NOP, &short_reg_data[22], 0);
ret += otm8009a_write_reg(&pObj->Ctx, 0xC0, &short_reg_data[23], 0);
/* Power control 1 */
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_NOP, &short_reg_data[24], 0);
ret += otm8009a_write_reg(&pObj->Ctx, 0xC5, &short_reg_data[25], 0);
/* Source driver precharge */
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_NOP, &short_reg_data[13], 0);
ret += otm8009a_write_reg(&pObj->Ctx, 0xC4, &short_reg_data[26], 0);
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_NOP, &short_reg_data[15], 0);
ret += otm8009a_write_reg(&pObj->Ctx, 0xC1, &short_reg_data[27], 0);
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_NOP, &short_reg_data[28], 0);
ret += otm8009a_write_reg(&pObj->Ctx, 0xB3, lcd_reg_data6, 2);
/* GOAVST */
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_NOP, &short_reg_data[2], 0);
ret += otm8009a_write_reg(&pObj->Ctx, 0xCE, lcd_reg_data7, 6);
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_NOP, &short_reg_data[29], 0);
ret += otm8009a_write_reg(&pObj->Ctx, 0xCE, lcd_reg_data8, 14);
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_NOP, &short_reg_data[30], 0);
ret += otm8009a_write_reg(&pObj->Ctx, 0xCE, lcd_reg_data9, 14);
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_NOP, &short_reg_data[31], 0);
ret += otm8009a_write_reg(&pObj->Ctx, 0xCF, lcd_reg_data10, 10);
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_NOP, &short_reg_data[32], 0);
ret += otm8009a_write_reg(&pObj->Ctx, 0xCF, &short_reg_data[45], 0);
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_NOP, &short_reg_data[2], 0);
ret += otm8009a_write_reg(&pObj->Ctx, 0xCB, lcd_reg_data11, 10);
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_NOP, &short_reg_data[33], 0);
ret += otm8009a_write_reg(&pObj->Ctx, 0xCB, lcd_reg_data12, 15);
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_NOP, &short_reg_data[29], 0);
ret += otm8009a_write_reg(&pObj->Ctx, 0xCB, lcd_reg_data13, 15);
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_NOP, &short_reg_data[30], 0);
ret += otm8009a_write_reg(&pObj->Ctx, 0xCB, lcd_reg_data14, 10);
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_NOP, &short_reg_data[31], 0);
ret += otm8009a_write_reg(&pObj->Ctx, 0xCB, lcd_reg_data15, 15);
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_NOP, &short_reg_data[32], 0);
ret += otm8009a_write_reg(&pObj->Ctx, 0xCB, lcd_reg_data16, 15);
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_NOP, &short_reg_data[34], 0);
ret += otm8009a_write_reg(&pObj->Ctx, 0xCB, lcd_reg_data17, 10);
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_NOP, &short_reg_data[35], 0);
ret += otm8009a_write_reg(&pObj->Ctx, 0xCB, lcd_reg_data18, 10);
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_NOP, &short_reg_data[2], 0);
ret += otm8009a_write_reg(&pObj->Ctx, 0xCC, lcd_reg_data19, 10);
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_NOP, &short_reg_data[33], 0);
ret += otm8009a_write_reg(&pObj->Ctx, 0xCC, lcd_reg_data20, 15);
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_NOP, &short_reg_data[29], 0);
ret += otm8009a_write_reg(&pObj->Ctx, 0xCC, lcd_reg_data21, 15);
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_NOP, &short_reg_data[30], 0);
ret += otm8009a_write_reg(&pObj->Ctx, 0xCC, lcd_reg_data22, 10);
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_NOP, &short_reg_data[31], 0);
ret += otm8009a_write_reg(&pObj->Ctx, 0xCC, lcd_reg_data23, 15);
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_NOP, &short_reg_data[32], 0);
ret += otm8009a_write_reg(&pObj->Ctx, 0xCC, lcd_reg_data24, 15);
/////////////////////////////////////////////////////////////////////////////
/* PWR_CTRL1 - 0xc580h - 130th parameter - default 0x00 */
/* Pump 1 min and max DM */
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_NOP, &short_reg_data[13], 0);
ret += otm8009a_write_reg(&pObj->Ctx, 0xC5, &short_reg_data[46], 0);
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_NOP, &short_reg_data[47], 0);
ret += otm8009a_write_reg(&pObj->Ctx, 0xF5, &short_reg_data[48], 0);
/////////////////////////////////////////////////////////////////////////////
/* CABC LEDPWM frequency adjusted to 19,5kHz */
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_NOP, &short_reg_data[49], 0);
ret += otm8009a_write_reg(&pObj->Ctx, 0xC6, &short_reg_data[50], 0);
/* Exit CMD2 mode */
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_NOP, &short_reg_data[1], 0);
ret += otm8009a_write_reg(&pObj->Ctx, 0xFF, lcd_reg_data25, 3);
/*************************************************************************** */
/* Standard DCS Initialization TO KEEP CAN BE DONE IN HSDT */
/*************************************************************************** */
/* NOP - goes back to DCS std command ? */
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_NOP, &short_reg_data[1], 0);
/* Gamma correction 2.2+ table (HSDT possible) */
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_NOP, &short_reg_data[1], 0);
ret += otm8009a_write_reg(&pObj->Ctx, 0xE1, lcd_reg_data3, 16);
/* Gamma correction 2.2- table (HSDT possible) */
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_NOP, &short_reg_data[1], 0);
ret += otm8009a_write_reg(&pObj->Ctx, 0xE2, lcd_reg_data4, 16);
/* Send Sleep Out command to display : no parameter */
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_SLPOUT, &short_reg_data[36], 0);
/* Wait for sleep out exit */
(void)OTM8009A_IO_Delay(pObj, 120);
switch(ColorCoding)
{
case OTM8009A_FORMAT_RBG565 :
/* Set Pixel color format to RGB565 */
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_COLMOD, &short_reg_data[37], 0);
OTM8009ACtx.ColorCode = OTM8009A_FORMAT_RBG565;
break;
case OTM8009A_FORMAT_RGB888 :
/* Set Pixel color format to RGB888 */
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_COLMOD, &short_reg_data[38], 0);
OTM8009ACtx.ColorCode = OTM8009A_FORMAT_RGB888;
break;
default :
break;
}
/* Send command to configure display in landscape orientation mode. By default
the orientation mode is portrait */
if(Orientation == OTM8009A_ORIENTATION_LANDSCAPE)
{
uint8_t tmp = OTM8009A_MADCTR_MODE_LANDSCAPE;
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_MADCTR, &tmp, 0);
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_CASET, LcdRegData27, 4);
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_PASET, LcdRegData28, 4);
OTM8009ACtx.Orientation = OTM8009A_ORIENTATION_LANDSCAPE;
}
else
{
OTM8009ACtx.Orientation = OTM8009A_ORIENTATION_PORTRAIT;
}
/** CABC : Content Adaptive Backlight Control section start >> */
/* Note : defaut is 0 (lowest Brightness], 0xFF is highest Brightness, try 0x7F : intermediate value */
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_WRDISBV, &short_reg_data[39], 0);
/* Store default brightness */
OTM8009ACtx.Brightness = ((uint32_t)short_reg_data[39] / 0xFFU) * 100U;
/* defaut is 0, try 0x2C - Brightness Control Block, Display Dimming & BackLight on */
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_WRCTRLD, &short_reg_data[40], 0);
/* defaut is 0, try 0x02 - image Content based Adaptive Brightness [Still Picture] */
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_WRCABC, &short_reg_data[41], 0);
/* defaut is 0 (lowest Brightness], 0xFF is highest Brightness */
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_WRCABCMB, &short_reg_data[42], 0);
/** CABC : Content Adaptive Backlight Control section end << */
/* Send Command Display On */
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_DISPON, &short_reg_data[43], 0);
/* NOP command */
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_NOP, &short_reg_data[1], 0);
/* Send Command GRAM memory write (no parameters) : this initiates frame write via other DSI commands sent by */
/* DSI host from LTDC incoming pixels in video mode */
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_RAMWR, &short_reg_data[44], 0);
if(ret != OTM8009A_OK)
{
ret = OTM8009A_ERROR;
}
return ret;
}
/**
* @brief De-Initializes the component
* @param pObj Component object
* @retval Component status
*/
int32_t OTM8009A_DeInit(OTM8009A_Object_t *pObj)
{
return OTM8009A_ERROR;
}
/**
* @brief Read the component ID.
* @param pObj Component object
* @param Id Component ID
* @retval Component status
*/
int32_t OTM8009A_ReadID(OTM8009A_Object_t *pObj, uint32_t *Id)
{
int32_t ret;
if(otm8009a_read_reg(&pObj->Ctx, OTM8009A_CMD_ID1, (uint8_t *)Id, 1)!= OTM8009A_OK)
{
ret = OTM8009A_ERROR;
}
else
{
ret = OTM8009A_OK;
}
return ret;
}
/**
* @brief Set the display brightness.
* @param pObj Component object
* @param Brightness display brightness to be set
* @retval Component status
*/
int32_t OTM8009A_SetBrightness(OTM8009A_Object_t *pObj, uint32_t Brightness)
{
int32_t ret;
uint8_t brightness = (uint8_t)((Brightness * 255U)/100U);
/* Send Display on DCS command to display */
if(otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_WRDISBV, &brightness, 0) != OTM8009A_OK)
{
ret = OTM8009A_ERROR;
}
else
{
OTM8009ACtx.Brightness = Brightness;
ret = OTM8009A_OK;
}
return ret;
}
/**
* @brief Get the display brightness.
* @param pObj Component object
* @param Brightness display brightness to be returned
* @retval Component status
*/
int32_t OTM8009A_GetBrightness(OTM8009A_Object_t *pObj, uint32_t *Brightness)
{
*Brightness = OTM8009ACtx.Brightness;
return OTM8009A_OK;
}
/**
* @brief Set the display On.
* @param pObj Component object
* @retval Component status
*/
int32_t OTM8009A_DisplayOn(OTM8009A_Object_t *pObj)
{
int32_t ret;
uint8_t display = 0;
/* Send Display on DCS command to display */
if(otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_DISPON, &display, 0) != OTM8009A_OK)
{
ret = OTM8009A_ERROR;
}
else
{
ret = OTM8009A_OK;
}
return ret;
}
/**
* @brief Set the display Off.
* @param pObj Component object
* @retval Component status
*/
int32_t OTM8009A_DisplayOff(OTM8009A_Object_t *pObj)
{
int32_t ret;
uint8_t display = 0;
/* Send Display on DCS command to display */
if(otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_DISPOFF, &display, 0) != OTM8009A_OK)
{
ret = OTM8009A_ERROR;
}
else
{
ret = OTM8009A_OK;
}
return ret;
}
/**
* @brief Set the display Orientation.
* @param pObj Component object
* @param Orientation display Orientation to be set
* @retval Component status
*/
int32_t OTM8009A_SetOrientation(OTM8009A_Object_t *pObj, uint32_t Orientation)
{
int32_t ret;
uint8_t tmp = OTM8009A_MADCTR_MODE_LANDSCAPE;
uint8_t tmp1 = OTM8009A_MADCTR_MODE_PORTRAIT;
if((Orientation != OTM8009A_ORIENTATION_LANDSCAPE) && (Orientation != OTM8009A_ORIENTATION_PORTRAIT))
{
ret = OTM8009A_ERROR;
}/* Send command to configure display orientation mode */
else if(Orientation == OTM8009A_ORIENTATION_LANDSCAPE)
{
ret = otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_MADCTR, &tmp, 0);
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_CASET, LcdRegData27, 4);
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_PASET, LcdRegData28, 4);
OTM8009ACtx.Orientation = OTM8009A_ORIENTATION_LANDSCAPE;
}
else
{
ret = otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_MADCTR, &tmp1, 0);
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_CASET, LcdRegData27, 4);
ret += otm8009a_write_reg(&pObj->Ctx, OTM8009A_CMD_PASET, LcdRegData28, 4);
OTM8009ACtx.Orientation = OTM8009A_ORIENTATION_PORTRAIT;
}
if(ret != OTM8009A_OK)
{
ret = OTM8009A_ERROR;
}
return ret;
}
/**
* @brief Set the display Orientation.
* @param pObj Component object
* @param Orientation display Orientation to be returned
* @retval Component status
*/
int32_t OTM8009A_GetOrientation(OTM8009A_Object_t *pObj, uint32_t *Orientation)
{
/* Prevent unused argument(s) compilation warning */
(void)(pObj);
*Orientation = OTM8009ACtx.Orientation;
return OTM8009A_OK;
}
/**
* @brief Set the display Width.
* @param pObj Component object
* @param Xsize display Width to be set
* @retval Component status
*/
int32_t OTM8009A_GetXSize(OTM8009A_Object_t *pObj, uint32_t *Xsize)
{
/* Prevent unused argument(s) compilation warning */
(void)(pObj);
switch(OTM8009ACtx.Orientation)
{
case OTM8009A_ORIENTATION_PORTRAIT:
*Xsize = OTM8009A_480X800_WIDTH;
break;
case OTM8009A_ORIENTATION_LANDSCAPE:
*Xsize = OTM8009A_800X480_WIDTH;
break;
default:
*Xsize = OTM8009A_800X480_WIDTH;
break;
}
return OTM8009A_OK;
}
/**
* @brief Set the display Height.
* @param pObj Component object
* @param Ysize display Height to be set
* @retval Component status
*/
int32_t OTM8009A_GetYSize(OTM8009A_Object_t *pObj, uint32_t *Ysize)
{
/* Prevent unused argument(s) compilation warning */
(void)(pObj);
switch(OTM8009ACtx.Orientation)
{
case OTM8009A_ORIENTATION_PORTRAIT:
*Ysize = OTM8009A_480X800_HEIGHT;
break;
case OTM8009A_ORIENTATION_LANDSCAPE:
*Ysize = OTM8009A_800X480_HEIGHT;
break;
default:
*Ysize = OTM8009A_800X480_HEIGHT;
break;
}
return OTM8009A_OK;
}
/**
* @brief Set the display cursor.
* @param pObj Component object
* @param Xpos X position
* @param Ypos Y position
* @retval Component status
*/
int32_t OTM8009A_SetCursor(OTM8009A_Object_t *pObj, uint32_t Xpos, uint32_t Ypos)
{
/* Prevent unused argument(s) compilation warning */
(void)(pObj);
return OTM8009A_ERROR;
}
/**
* @brief Draw Bitmap image
* @param pObj Component object
* @param Xpos X position
* @param Ypos Y position
* @param pBmp pointer to bmp data
* @retval Component status
*/
int32_t OTM8009A_DrawBitmap(OTM8009A_Object_t *pObj, uint32_t Xpos, uint32_t Ypos, uint8_t *pBmp)
{
/* Prevent unused argument(s) compilation warning */
(void)(pObj);
return OTM8009A_ERROR;
}
int32_t OTM8009A_FillRGBRect(OTM8009A_Object_t *pObj, uint32_t Xpos, uint32_t Ypos, uint8_t *pData, uint32_t Width, uint32_t Height)
{
/* Prevent unused argument(s) compilation warning */
(void)(pObj);
return OTM8009A_ERROR;
}
/**
* @brief Draw Horizontal Line
* @param pObj Component object
* @param Xpos X position
* @param Ypos Y position
* @param Length Line length
* @param Color Draw color
* @retval Component status
*/
int32_t OTM8009A_DrawHLine(OTM8009A_Object_t *pObj, uint32_t Xpos, uint32_t Ypos, uint32_t Length, uint32_t Color)
{
/* Prevent unused argument(s) compilation warning */
(void)(pObj);
return OTM8009A_ERROR;
}
/**
* @brief Draw Vertical line
* @param pObj Component object
* @param Xpos X position
* @param Ypos Y position
* @param Length Line length
* @param Color Draw color
* @retval Component status
*/
int32_t OTM8009A_DrawVLine(OTM8009A_Object_t *pObj, uint32_t Xpos, uint32_t Ypos, uint32_t Length, uint32_t Color)
{
/* Prevent unused argument(s) compilation warning */
(void)(pObj);
return OTM8009A_ERROR;
}
/**
* @brief Fill rectangle
* @param pObj Component object
* @param Xpos X position
* @param Ypos Y position
* @param Width Rectangle width
* @param Height Rectangle height
* @param Color Draw color
* @retval Component status
*/
int32_t OTM8009A_FillRect(OTM8009A_Object_t *pObj, uint32_t Xpos, uint32_t Ypos, uint32_t Width, uint32_t Height, uint32_t Color)
{
/* Prevent unused argument(s) compilation warning */
(void)(pObj);
return OTM8009A_ERROR;
}
/**
* @brief Get pixel color
* @param pObj Component object
* @param Xpos X position
* @param Ypos Y position
* @param Color Color to be returned
* @retval Component status
*/
int32_t OTM8009A_GetPixel(OTM8009A_Object_t *pObj, uint32_t Xpos, uint32_t Ypos, uint32_t *Color)
{
/* Prevent unused argument(s) compilation warning */
(void)(pObj);
return OTM8009A_ERROR;
}
/**
* @brief Set pixel color
* @param pObj Component object
* @param Xpos X position
* @param Ypos Y position
* @param Color Color to be returned
* @retval Component status
*/
int32_t OTM8009A_SetPixel(OTM8009A_Object_t *pObj, uint32_t Xpos, uint32_t Ypos, uint32_t Color)
{
/* Prevent unused argument(s) compilation warning */
(void)(pObj);
return OTM8009A_ERROR;
}
/**
* @}
*/
/** @addtogroup OTM8009A_Private_FunctionsPrototyes
* @{
*/
/**
* @brief Wrap component ReadReg to Bus Read function
* @param Handle Component object handle
* @param Reg The target register address to write
* @param pData The target register value to be written
* @param Length buffer size to be written
* @retval error status
*/
static int32_t OTM8009A_ReadRegWrap(void *Handle, uint16_t Reg, uint8_t* pData, uint16_t Length)
{
OTM8009A_Object_t *pObj = (OTM8009A_Object_t *)Handle;
return pObj->IO.ReadReg(pObj->IO.Address, Reg, pData, Length);
}
/**
* @brief Wrap component WriteReg to Bus Write function
* @param handle Component object handle
* @param Reg The target register address to write
* @param pData The target register value to be written
* @param Length buffer size to be written
* @retval error status
*/
static int32_t OTM8009A_WriteRegWrap(void *Handle, uint16_t Reg, uint8_t *pData, uint16_t Length)
{
OTM8009A_Object_t *pObj = (OTM8009A_Object_t *)Handle;
return pObj->IO.WriteReg(pObj->IO.Address, Reg, pData, Length);
}
/**
* @brief OTM8009A delay
* @param Delay Delay in ms
*/
static int32_t OTM8009A_IO_Delay(OTM8009A_Object_t *pObj, uint32_t Delay)
{
uint32_t tickstart;
tickstart = pObj->IO.GetTick();
while((pObj->IO.GetTick() - tickstart) < Delay)
{
}
return OTM8009A_OK;
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/