72041911ce
Marco Krahl has submitted the ICLA and we can migrate the licenses to Apache. Gregory Nutt, S.A has submitted the SGA and we can migrate the licenses to Apache. Signed-off-by: Alin Jerpelea <alin.jerpelea@sony.com>
595 lines
16 KiB
C
595 lines
16 KiB
C
/****************************************************************************
|
|
* drivers/lcd/lpm013m091a.c
|
|
*
|
|
* 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 <sys/types.h>
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
#include <debug.h>
|
|
|
|
#include <nuttx/arch.h>
|
|
#include <nuttx/lcd/lcd.h>
|
|
#include <nuttx/lcd/lpm013m091a.h>
|
|
|
|
/****************************************************************************
|
|
* Pre-processor Definitions
|
|
****************************************************************************/
|
|
|
|
/* Display resolution */
|
|
|
|
#define LPM013M091A_XRES 320
|
|
#define LPM013M091A_YRES 300
|
|
|
|
/* TODO: Stride should be configurable by LCD orientation */
|
|
|
|
#define LPM013M091A_STRIDE LPM013M091A_XRES
|
|
|
|
/* Dolor depth and format */
|
|
|
|
#define LPM013M091A_BPP 16
|
|
#define LPM013M091A_COLORFMT FB_FMT_RGB16_565
|
|
|
|
/****************************************************************************
|
|
* Private types
|
|
****************************************************************************/
|
|
|
|
struct lpm013m091a_dev_s
|
|
{
|
|
/* Publicly visible device structure */
|
|
|
|
struct lcd_dev_s dev;
|
|
|
|
/* Private lcd-specific information follows */
|
|
|
|
struct lpm013m091a_lcd_s *lcd;
|
|
|
|
uint8_t power; /* Current power setting */
|
|
};
|
|
|
|
/****************************************************************************
|
|
* Private Function Protototypes
|
|
****************************************************************************/
|
|
|
|
static void lpm013m091a_selectarea(FAR struct lpm013m091a_lcd_s *lcd,
|
|
uint16_t x0, int16_t y0,
|
|
uint16_t x1, int16_t y1);
|
|
static int lpm013m091a_hwinitialize(FAR struct lpm013m091a_dev_s *dev);
|
|
|
|
/* lcd data transfer methods */
|
|
|
|
static int lpm013m091a_putrun(fb_coord_t row, fb_coord_t col,
|
|
FAR const uint8_t *buffer, size_t npixels);
|
|
#ifndef CONFIG_LCD_NOGETRUN
|
|
static int lpm013m091a_getrun(fb_coord_t row, fb_coord_t col,
|
|
FAR uint8_t *buffer,
|
|
size_t npixels);
|
|
#endif
|
|
|
|
/* lcd configuration */
|
|
|
|
static int lpm013m091a_getvideoinfo(FAR struct lcd_dev_s *dev,
|
|
FAR struct fb_videoinfo_s *vinfo);
|
|
static int lpm013m091a_getplaneinfo(FAR struct lcd_dev_s *dev,
|
|
unsigned int planeno,
|
|
FAR struct lcd_planeinfo_s *pinfo);
|
|
|
|
/* lcd specific controls */
|
|
|
|
static int lpm013m091a_getpower(FAR struct lcd_dev_s *dev);
|
|
static int lpm013m091a_setpower(FAR struct lcd_dev_s *dev, int power);
|
|
static int lpm013m091a_getcontrast(FAR struct lcd_dev_s *dev);
|
|
static int lpm013m091a_setcontrast(FAR struct lcd_dev_s *dev,
|
|
unsigned int contrast);
|
|
|
|
/****************************************************************************
|
|
* Private Data
|
|
****************************************************************************/
|
|
|
|
static uint16_t g_runbuffer[LPM013M091A_STRIDE];
|
|
|
|
/* This structure describes the overall lcd video controller */
|
|
|
|
static const struct fb_videoinfo_s g_videoinfo =
|
|
{
|
|
.fmt = LPM013M091A_COLORFMT, /* Color format: rgb16-565: rrrr rggg gggb bbbb */
|
|
.xres = LPM013M091A_XRES, /* Horizontal resolution in pixel columns */
|
|
.yres = LPM013M091A_YRES, /* Vertical resolution in pixel rows */
|
|
.nplanes = 1, /* Number of color planes supported */
|
|
};
|
|
|
|
/* This is the standard, nuttx plane information object */
|
|
|
|
static const struct lcd_planeinfo_s g_planeinfo =
|
|
{
|
|
.putrun = lpm013m091a_putrun, /* Put a run into lcd memory */
|
|
#ifndef CONFIG_LCD_NOGETRUN
|
|
.getrun = lpm013m091a_getrun, /* Get a run from lcd memory */
|
|
#endif
|
|
.buffer = (uint8_t *) g_runbuffer, /* Run scratch buffer */
|
|
.bpp = LPM013M091A_BPP, /* Bits-per-pixel */
|
|
};
|
|
|
|
static struct lpm013m091a_dev_s g_lpm013m091a_dev =
|
|
{
|
|
.dev =
|
|
{
|
|
/* lcd configuration */
|
|
|
|
.getvideoinfo = lpm013m091a_getvideoinfo,
|
|
.getplaneinfo = lpm013m091a_getplaneinfo,
|
|
|
|
/* lcd specific controls */
|
|
|
|
.getpower = lpm013m091a_getpower,
|
|
.setpower = lpm013m091a_setpower,
|
|
.getcontrast = lpm013m091a_getcontrast,
|
|
.setcontrast = lpm013m091a_setcontrast,
|
|
},
|
|
.lcd = 0,
|
|
};
|
|
|
|
/****************************************************************************
|
|
* Private Functions
|
|
****************************************************************************/
|
|
|
|
/****************************************************************************
|
|
* Name: lpm013m091a_selectarea
|
|
*
|
|
* Description:
|
|
* Select the active area for displaying pixel
|
|
*
|
|
* Parameter:
|
|
* lcd - Reference to private driver structure
|
|
* x0 - Start x position
|
|
* y0 - Start y position
|
|
* x1 - End x position
|
|
* y1 - End y position
|
|
*
|
|
****************************************************************************/
|
|
|
|
static void lpm013m091a_selectarea(FAR struct lpm013m091a_lcd_s *lcd,
|
|
uint16_t x0, int16_t y0,
|
|
uint16_t x1, int16_t y1)
|
|
{
|
|
lcd->sendcmd(lcd, LPM013M091A_CASET);
|
|
lcd->sendparam(lcd, x0 >> 8);
|
|
lcd->sendparam(lcd, x0 & 0xff);
|
|
lcd->sendparam(lcd, x1 >> 8);
|
|
lcd->sendparam(lcd, x1 & 0xff);
|
|
|
|
lcd->sendcmd(lcd, LPM013M091A_PASET);
|
|
lcd->sendparam(lcd, y0 >> 8);
|
|
lcd->sendparam(lcd, y0 & 0xff);
|
|
lcd->sendparam(lcd, y1 >> 8);
|
|
lcd->sendparam(lcd, y1 & 0xff);
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Name: lpm013m091a_hwinitialize
|
|
*
|
|
* Description:
|
|
* Initialize and configure the LPM013M091A LCD driver hardware.
|
|
*
|
|
* Parameter:
|
|
* dev - A reference to the driver specific structure
|
|
*
|
|
* Returned Value:
|
|
*
|
|
* On success - OK
|
|
* On error - EINVAL
|
|
*
|
|
****************************************************************************/
|
|
|
|
static int lpm013m091a_hwinitialize(FAR struct lpm013m091a_dev_s *dev)
|
|
{
|
|
FAR struct lpm013m091a_lcd_s *lcd = dev->lcd;
|
|
|
|
/* Soft reset */
|
|
|
|
lcd->sendcmd(lcd, LPM013M091A_SWRESET);
|
|
up_mdelay(10);
|
|
|
|
/* Analog mode */
|
|
|
|
lcd->sendcmd(lcd, 0xb3);
|
|
lcd->sendparam(lcd, 0x02);
|
|
|
|
/* Set Display Mode */
|
|
|
|
lcd->sendcmd(lcd, 0xbb);
|
|
lcd->sendparam(lcd, 0x10);
|
|
|
|
/* SPI GRAM access enable */
|
|
|
|
lcd->sendcmd(lcd, 0xf3);
|
|
lcd->sendparam(lcd, 0x02);
|
|
|
|
/* Bright Level Max */
|
|
|
|
lcd->sendcmd(lcd, 0x51);
|
|
lcd->sendparam(lcd, 0xff);
|
|
|
|
/* Backlight ON */
|
|
|
|
lcd->sendcmd(lcd, 0x53);
|
|
lcd->sendparam(lcd, 0x24);
|
|
|
|
/* Frame rate 60Hz */
|
|
|
|
lcd->sendcmd(lcd, 0xff);
|
|
lcd->sendparam(lcd, 0x24);
|
|
lcd->sendcmd(lcd, 0xd8);
|
|
lcd->sendparam(lcd, 0x41);
|
|
lcd->sendcmd(lcd, 0xd9);
|
|
lcd->sendparam(lcd, 0x1e);
|
|
|
|
lcd->sendcmd(lcd, 0xff);
|
|
lcd->sendparam(lcd, 0x10);
|
|
|
|
/* Set the color format (18bit:0x06, 16bit:0x05) */
|
|
|
|
lcd->sendcmd(lcd, LPM013M091A_PIXFMT);
|
|
lcd->sendparam(lcd, 0x05);
|
|
|
|
/* Sleep out */
|
|
|
|
lcd->sendcmd(lcd, LPM013M091A_SLPOUT);
|
|
up_mdelay(10);
|
|
|
|
/* Display on */
|
|
|
|
lcd->sendcmd(lcd, LPM013M091A_DISPON);
|
|
up_mdelay(120);
|
|
|
|
return OK;
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Name: lpm013m091a_putrun
|
|
*
|
|
* Description:
|
|
* Write a partial raster line to the LCD.
|
|
*
|
|
* Parameters:
|
|
* devno - Number of lcd device
|
|
* row - Starting row to write to (range: 0 <= row < yres)
|
|
* col - Starting column to write to (range: 0 <= col <= xres-npixels)
|
|
* buffer - The buffer containing the run to be written to the LCD
|
|
* npixels - The number of pixels to write to the
|
|
* (range: 0 < npixels <= xres-col)
|
|
*
|
|
* Returned Value:
|
|
*
|
|
* On success - OK
|
|
* On error - -EINVAL
|
|
*
|
|
****************************************************************************/
|
|
|
|
static int lpm013m091a_putrun(fb_coord_t row, fb_coord_t col,
|
|
FAR const uint8_t *buffer, size_t npixels)
|
|
{
|
|
FAR struct lpm013m091a_dev_s *dev = (FAR struct lpm013m091a_dev_s *)
|
|
&g_lpm013m091a_dev;
|
|
FAR struct lpm013m091a_lcd_s *lcd = dev->lcd;
|
|
FAR const uint16_t *src = (FAR const uint16_t *)buffer;
|
|
|
|
DEBUGASSERT(buffer && ((uintptr_t)buffer & 1) == 0);
|
|
|
|
/* Check if position outside of area */
|
|
|
|
if (col + npixels > LPM013M091A_XRES || row > LPM013M091A_YRES)
|
|
{
|
|
return -EINVAL;
|
|
}
|
|
|
|
/* Select lcd driver */
|
|
|
|
lcd->select(lcd);
|
|
|
|
/* Select column and area similar to the partial raster line */
|
|
|
|
lpm013m091a_selectarea(lcd, col, row, col + npixels - 1, row);
|
|
|
|
/* Send memory write cmd */
|
|
|
|
lcd->sendcmd(lcd, LPM013M091A_RAMWR);
|
|
|
|
/* Send pixel to gram */
|
|
|
|
lcd->sendgram(lcd, src, npixels);
|
|
|
|
/* Deselect the lcd driver */
|
|
|
|
lcd->deselect(lcd);
|
|
|
|
return OK;
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Name: lpm013m091a_getrun
|
|
*
|
|
* Description:
|
|
* Read a partial raster line from the LCD.
|
|
*
|
|
* Parameter:
|
|
* devno - Number of the lcd device
|
|
* row - Starting row to read from (range: 0 <= row < yres)
|
|
* col - Starting column to read read (range: 0 <= col <= xres-npixels)
|
|
* buffer - The buffer in which to return the run read from the LCD
|
|
* npixels - The number of pixels to read from the LCD
|
|
* (range: 0 < npixels <= xres-col)
|
|
*
|
|
* Returned Value:
|
|
*
|
|
* On success - OK
|
|
* On error - -EINVAL
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifndef CONFIG_LCD_NOGETRUN
|
|
int lpm013m091a_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t * buffer,
|
|
size_t npixels)
|
|
{
|
|
lcderr("getrun is not supported for now.\n");
|
|
return -ENOSYS;
|
|
}
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: lpm013m091a_getvideoinfo
|
|
*
|
|
* Description:
|
|
* Get information about the LCD video controller configuration.
|
|
*
|
|
* Parameter:
|
|
* dev - A reference to the driver specific structure
|
|
* vinfo - A reference to the videoinfo structure
|
|
*
|
|
* Returned Value:
|
|
*
|
|
* On success - OK
|
|
* On error - -EINVAL
|
|
*
|
|
****************************************************************************/
|
|
|
|
static int lpm013m091a_getvideoinfo(FAR struct lcd_dev_s *dev,
|
|
FAR struct fb_videoinfo_s *vinfo)
|
|
{
|
|
if (dev && vinfo)
|
|
{
|
|
memcpy(vinfo, &g_videoinfo, sizeof(struct fb_videoinfo_s));
|
|
|
|
lcdinfo("fmt: %d xres: %d yres: %d nplanes: %d\n",
|
|
vinfo->fmt, vinfo->xres, vinfo->yres, vinfo->nplanes);
|
|
|
|
return OK;
|
|
}
|
|
|
|
return -EINVAL;
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Name: lpm013m091a_getplaneinfo
|
|
*
|
|
* Description:
|
|
* Get information about the configuration of each LCD color plane.
|
|
*
|
|
* Parameter:
|
|
* dev - A reference to the driver specific structure
|
|
* planeno - The plane number
|
|
* pinfo - A reference to the planeinfo structure
|
|
*
|
|
* Returned Value:
|
|
*
|
|
* On success - OK
|
|
* On error - -EINVAL
|
|
*
|
|
****************************************************************************/
|
|
|
|
static int lpm013m091a_getplaneinfo(FAR struct lcd_dev_s *dev,
|
|
unsigned int planeno,
|
|
FAR struct lcd_planeinfo_s *pinfo)
|
|
{
|
|
if (dev && pinfo && planeno == 0)
|
|
{
|
|
memcpy(pinfo, &g_planeinfo, sizeof(struct lcd_planeinfo_s));
|
|
|
|
lcdinfo("planeno: %d bpp: %d\n", planeno, pinfo->bpp);
|
|
|
|
return OK;
|
|
}
|
|
|
|
return -EINVAL;
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Name: lpm013m091a_getpower
|
|
*
|
|
* Description:
|
|
* Get the LCD panel power status
|
|
* 0: full off - CONFIG_LCD_MAXPOWER: full on.
|
|
* On backlit LCDs, this setting may correspond to the backlight setting.
|
|
*
|
|
* Parameter:
|
|
* dev - A reference to the driver specific structure
|
|
*
|
|
* Returned Value:
|
|
*
|
|
* On success - OK
|
|
* On error - -EINVAL
|
|
*
|
|
****************************************************************************/
|
|
|
|
static int lpm013m091a_getpower(FAR struct lcd_dev_s *dev)
|
|
{
|
|
FAR struct lpm013m091a_dev_s *priv = (FAR struct lpm013m091a_dev_s *)dev;
|
|
|
|
lcdinfo("%d\n", priv->power);
|
|
return priv->power;
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Name: lpm013m091a_setpower
|
|
*
|
|
* Description:
|
|
* Enable/disable LCD panel power
|
|
* (0: full off - CONFIG_LCD_MAXPOWER: full on).
|
|
* On backlight LCDs, this setting may correspond to the backlight setting.
|
|
*
|
|
* Parameter:
|
|
* dev - A reference to the driver specific structure
|
|
* power - Value of the power
|
|
*
|
|
* Returned Value:
|
|
*
|
|
* On success - OK
|
|
* On error - -EINVAL
|
|
*
|
|
****************************************************************************/
|
|
|
|
static int lpm013m091a_setpower(FAR struct lcd_dev_s *dev, int power)
|
|
{
|
|
FAR struct lpm013m091a_dev_s *priv = (FAR struct lpm013m091a_dev_s *)dev;
|
|
FAR struct lpm013m091a_lcd_s *lcd = priv->lcd;
|
|
|
|
if (!dev)
|
|
{
|
|
return -EINVAL;
|
|
}
|
|
|
|
lcdinfo("%d\n", power);
|
|
|
|
lcd->select(lcd);
|
|
|
|
if (power > 0)
|
|
{
|
|
lcd->backlight(lcd, power);
|
|
|
|
lcd->sendcmd(lcd, LPM013M091A_DISPON);
|
|
up_mdelay(120);
|
|
}
|
|
else
|
|
{
|
|
lcd->sendcmd(lcd, LPM013M091A_DISPOFF);
|
|
}
|
|
|
|
lcd->deselect(lcd);
|
|
|
|
priv->power = power;
|
|
|
|
return OK;
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Name: ili9340_getcontrast
|
|
*
|
|
* Description:
|
|
* Get the current contrast setting (0-CONFIG_LCD_MAXCONTRAST).
|
|
*
|
|
* Parameter:
|
|
* dev - A reference to the lcd driver structure
|
|
*
|
|
* Returned Value:
|
|
*
|
|
* On success - current contrast value
|
|
* On error - -ENOSYS, not supported by the ili9340.
|
|
*
|
|
****************************************************************************/
|
|
|
|
static int lpm013m091a_getcontrast(FAR struct lcd_dev_s *dev)
|
|
{
|
|
lcdinfo("Not implemented\n");
|
|
return -ENOSYS;
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Name: ili9340_setcontrast
|
|
*
|
|
* Description:
|
|
* Set LCD panel contrast (0-CONFIG_LCD_MAXCONTRAST).
|
|
*
|
|
* Parameter:
|
|
* dev - A reference to the lcd driver structure
|
|
*
|
|
* Returned Value:
|
|
*
|
|
* On success - OK
|
|
* On error - -ENOSYS, not supported by the ili9340.
|
|
*
|
|
****************************************************************************/
|
|
|
|
static int lpm013m091a_setcontrast(FAR struct lcd_dev_s *dev,
|
|
unsigned int contrast)
|
|
{
|
|
lcdinfo("Not implemented\n");
|
|
return -ENOSYS;
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Public Functions
|
|
****************************************************************************/
|
|
|
|
/****************************************************************************
|
|
* Initialize LCD
|
|
****************************************************************************/
|
|
|
|
FAR struct lcd_dev_s *
|
|
lpm013m091a_initialize(FAR struct lpm013m091a_lcd_s *lcd, int devno)
|
|
{
|
|
FAR struct lpm013m091a_dev_s *priv = &g_lpm013m091a_dev;
|
|
|
|
if (lcd && devno == 0)
|
|
{
|
|
if (!priv->lcd)
|
|
{
|
|
FAR struct lcd_dev_s *dev = &priv->dev;
|
|
int ret;
|
|
|
|
/* Initialize internal structure */
|
|
|
|
dev->getvideoinfo = lpm013m091a_getvideoinfo;
|
|
dev->getplaneinfo = lpm013m091a_getplaneinfo;
|
|
dev->getpower = lpm013m091a_getpower;
|
|
dev->setpower = lpm013m091a_setpower;
|
|
dev->getcontrast = lpm013m091a_getcontrast;
|
|
dev->setcontrast = lpm013m091a_setcontrast;
|
|
priv->lcd = lcd;
|
|
|
|
/* Initialize the LCD driver */
|
|
|
|
ret = lpm013m091a_hwinitialize(priv);
|
|
|
|
if (ret == OK)
|
|
{
|
|
return &priv->dev;
|
|
}
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|