2015-10-03 15:25:53 +02:00
|
|
|
/****************************************************************************
|
2014-10-20 23:19:43 +02:00
|
|
|
* drivers/lcd/ili9341.c
|
|
|
|
*
|
|
|
|
* LCD driver for the ILI9341 LCD Single Chip Driver
|
|
|
|
*
|
|
|
|
* Copyright (C) 2014 Marco Krahl. All rights reserved.
|
|
|
|
* Author: Marco Krahl <ocram.lhark@gmail.com>
|
|
|
|
*
|
|
|
|
* References: ILI9341_DS_V1.10.pdf (Rev: 1.10), "a-Si TFT LCD Single Chip
|
|
|
|
* Driver 240RGBx320 Resolution and 262K color",
|
|
|
|
* ILI TECHNOLOGY CORP., http://www.ilitek.com.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
*
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in
|
|
|
|
* the documentation and/or other materials provided with the
|
|
|
|
* distribution.
|
|
|
|
* 3. Neither the name NuttX nor the names of its contributors may be
|
|
|
|
* used to endorse or promote products derived from this software
|
|
|
|
* without specific prior writen permission.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
|
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
|
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
|
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
|
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
|
|
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
|
|
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
|
|
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*
|
2015-10-03 15:25:53 +02:00
|
|
|
****************************************************************************/
|
2014-10-20 23:19:43 +02:00
|
|
|
|
2015-10-03 15:25:53 +02:00
|
|
|
/****************************************************************************
|
2014-10-20 23:19:43 +02:00
|
|
|
* Included Files
|
2015-10-03 15:25:53 +02:00
|
|
|
****************************************************************************/
|
2014-10-20 23:19:43 +02:00
|
|
|
|
|
|
|
#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/ili9341.h>
|
|
|
|
|
|
|
|
#include <arch/irq.h>
|
|
|
|
|
2015-10-03 15:25:53 +02:00
|
|
|
/****************************************************************************
|
2014-10-20 23:19:43 +02:00
|
|
|
* Pre-processor Definitions
|
2015-10-03 15:25:53 +02:00
|
|
|
****************************************************************************/
|
2014-10-20 23:19:43 +02:00
|
|
|
|
2015-10-10 18:41:00 +02:00
|
|
|
/* This is the generic lcd driver interface for the ili9341 Single Chip LCD
|
2014-10-20 23:19:43 +02:00
|
|
|
* driver. The driver supports multiple displays, each connected with an own
|
|
|
|
* ili9341 Single Chip LCD driver. The communication with the LCD single chip
|
|
|
|
* driver must be provide by a subdriver accessable trough the ili9341_dev_s
|
|
|
|
* structure which is platform and MCU interface specific.
|
|
|
|
*
|
|
|
|
* Supported MCU interfaces (planed to support)
|
|
|
|
*
|
|
|
|
* Interface I
|
|
|
|
*
|
|
|
|
* 8080 MCU 8-bit bus interface
|
|
|
|
* 8080 MCU 16-bit bus interface
|
|
|
|
* 8080 MCU 9-bit bus interface
|
|
|
|
* 8080 MCU 18-bit bus interface
|
|
|
|
* 3-wire 9-bit data serial interface
|
|
|
|
* 4-wire 8-bit data serial interface
|
|
|
|
*
|
|
|
|
* Interface II
|
|
|
|
*
|
|
|
|
* 8080 MCU 8-bit bus interface
|
|
|
|
* 8080 MCU 16-bit bus interface
|
|
|
|
* 8080 MCU 9-bit bus interface
|
|
|
|
* 8080 MCU 18-bit bus interface
|
|
|
|
* 3-wire 9-bit data serial Interface
|
|
|
|
* 4-wire 8-bit data serial Interface
|
|
|
|
*
|
|
|
|
* Note! RGB interface will not supported by the lcd driver.
|
|
|
|
* It should be use with the platform specific RGB grapic controller and the
|
|
|
|
* nuttx framebuffer interface.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* Fundamental command and parameter definition */
|
|
|
|
|
|
|
|
/* Interface control (IFCTL)
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* Parameter 1: 0x0001
|
|
|
|
*
|
|
|
|
* MY_EOR: 0
|
|
|
|
* MX_EOR: 0
|
|
|
|
* MV_EOR: 0
|
|
|
|
* BGR_EOR: 0
|
|
|
|
* WEMODE: 1 Reset column and page if data transfer exceeds
|
|
|
|
*/
|
|
|
|
#define ILI9341_IFCTL_MYEOR 0
|
|
|
|
#define ILI9341_IFCTL_MXEOR 0
|
|
|
|
#define ILI9341_IFCTL_MVEOR 0
|
|
|
|
#define ILI9341_IFCTL_BGREOR 0
|
|
|
|
#define ILI9341_IFCTL_WEMODE ILI9341_INTERFACE_CONTROL_WEMODE
|
|
|
|
|
|
|
|
#define ILI9341_IFCTL_PARAM1 ILI9341_IFCTL_MYEOR | ILI9341_IFCTL_MXEOR | \
|
|
|
|
ILI9341_IFCTL_MVEOR | ILI9341_IFCTL_BGREOR | \
|
|
|
|
ILI9341_IFCTL_WEMODE
|
|
|
|
|
|
|
|
/* Parameter 2: 0x0000
|
|
|
|
*
|
|
|
|
* EPF: 0 65k color format for RGB interface, not used set to default
|
|
|
|
* MDT: 0 Display data transfer mode, not used
|
|
|
|
*
|
|
|
|
* Note! If RGB666 and 16-bit 8080-I interface supported by the driver, MDT must
|
|
|
|
* be defined for each selected driver instance. Leave it empty for now.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define ILI9341_IFCTL_EPF ILI9341_INTERFACE_CONTROL_EPF(0)
|
|
|
|
#define ILI9341_IFCTL_MDT ILI9341_INTERFACE_CONTROL_MDT(0)
|
|
|
|
|
|
|
|
#define ILI9341_IFCTL_PARAM2 ILI9341_IFCTL_EPF | ILI9341_IFCTL_MDT
|
|
|
|
|
|
|
|
|
|
|
|
/* Parameter 3: 0x0000/0x0020
|
|
|
|
*
|
|
|
|
* ENDIAN: 0/1 Depending on endian mode of the mcu?
|
|
|
|
* DM: 0 Internal clock operation
|
|
|
|
* RM: 0 System interface/VSYNC interface
|
|
|
|
* RIM: 0 RGB interface mode, unimportant set to default
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef CONFIG_ENDIAN_BIG
|
|
|
|
# define ILI9341_IFCTL_ENDIAN 0
|
|
|
|
#else
|
|
|
|
# define ILI9341_IFCTL_ENDIAN ILI9341_INTERFACE_CONTROL_ENDIAN
|
|
|
|
#endif
|
|
|
|
#define ILI9341_IFCTL_DM ILI9341_INTERFACE_CONTROL_DM(0)
|
|
|
|
#define ILI9341_IFCTL_RM 0
|
|
|
|
#define ILI9341_IFCTL_RIM 0
|
|
|
|
|
|
|
|
#define ILI9341_IFCTL_PARAM3 ILI9341_IFCTL_RIM | ILI9341_IFCTL_RM | \
|
|
|
|
ILI9341_IFCTL_DM | ILI9341_IFCTL_ENDIAN
|
|
|
|
|
|
|
|
|
|
|
|
/* Memory access control (MADCTL) */
|
|
|
|
|
2015-10-10 18:41:00 +02:00
|
|
|
/* Landscape: 00100000 / 00101000 / h28
|
2014-10-20 23:19:43 +02:00
|
|
|
*
|
|
|
|
* MY: 0
|
|
|
|
* MX: 0
|
|
|
|
* MV: 1
|
|
|
|
* ML: 0
|
|
|
|
* BGR: 0/1 Depending on endian mode of the mcu?
|
|
|
|
* MH: 0
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define ILI9341_MADCTL_LANDSCAPE_MY 0
|
|
|
|
#define ILI9341_MADCTL_LANDSCAPE_MX 0
|
|
|
|
#define ILI9341_MADCTL_LANDSCAPE_MV ILI9341_MEMORY_ACCESS_CONTROL_MV
|
|
|
|
#define ILI9341_MADCTL_LANDSCAPE_ML 0
|
|
|
|
#ifdef CONFIG_BIG_ENDIAN
|
|
|
|
# define ILI9341_MADCTL_LANDSCAPE_BGR 0
|
|
|
|
#else
|
|
|
|
# define ILI9341_MADCTL_LANDSCAPE_BGR ILI9341_MEMORY_ACCESS_CONTROL_BGR
|
|
|
|
#endif
|
|
|
|
#define ILI9341_MADCTL_LANDSCAPE_MH 0
|
|
|
|
|
|
|
|
#define ILI9341_MADCTL_LANDSCAPE_PARAM1 (ILI9341_MADCTL_LANDSCAPE_MY | \
|
|
|
|
ILI9341_MADCTL_LANDSCAPE_MX | \
|
|
|
|
ILI9341_MADCTL_LANDSCAPE_MV | \
|
|
|
|
ILI9341_MADCTL_LANDSCAPE_ML | \
|
|
|
|
ILI9341_MADCTL_LANDSCAPE_BGR | \
|
|
|
|
ILI9341_MADCTL_LANDSCAPE_MH)
|
|
|
|
|
2015-10-10 18:41:00 +02:00
|
|
|
/* Portrait: 00000000 / 00001000 / h08
|
2014-10-20 23:19:43 +02:00
|
|
|
*
|
|
|
|
* MY: 0
|
|
|
|
* MX: 0
|
|
|
|
* MV: 0
|
|
|
|
* ML: 0
|
|
|
|
* BGR: 0/1 Depending on endian mode of the mcu?
|
|
|
|
* MH: 0
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define ILI9341_MADCTL_PORTRAIT_MY 0
|
2015-11-25 20:01:37 +01:00
|
|
|
#define ILI9341_MADCTL_PORTRAIT_MX ILI9341_MEMORY_ACCESS_CONTROL_MX
|
2014-10-20 23:19:43 +02:00
|
|
|
#define ILI9341_MADCTL_PORTRAIT_MV 0
|
2015-11-25 20:01:37 +01:00
|
|
|
#define ILI9341_MADCTL_PORTRAIT_ML ILI9341_MEMORY_ACCESS_CONTROL_ML
|
2014-10-20 23:19:43 +02:00
|
|
|
#ifdef CONFIG_BIG_ENDIAN
|
|
|
|
# define ILI9341_MADCTL_PORTRAIT_BGR 0
|
|
|
|
#else
|
|
|
|
# define ILI9341_MADCTL_PORTRAIT_BGR ILI9341_MEMORY_ACCESS_CONTROL_BGR
|
|
|
|
#endif
|
|
|
|
#define ILI9341_MADCTL_PORTRAIT_MH 0
|
|
|
|
|
|
|
|
#define ILI9341_MADCTL_PORTRAIT_PARAM1 (ILI9341_MADCTL_PORTRAIT_MY | \
|
|
|
|
ILI9341_MADCTL_PORTRAIT_MX | \
|
|
|
|
ILI9341_MADCTL_PORTRAIT_MV | \
|
|
|
|
ILI9341_MADCTL_PORTRAIT_ML | \
|
|
|
|
ILI9341_MADCTL_PORTRAIT_BGR | \
|
|
|
|
ILI9341_MADCTL_PORTRAIT_MH)
|
2015-10-10 18:41:00 +02:00
|
|
|
/* RLandscape: 01100000 / 01101000 / h68
|
2014-10-20 23:19:43 +02:00
|
|
|
*
|
|
|
|
* MY: 0
|
|
|
|
* MX: 1
|
|
|
|
* MV: 1
|
|
|
|
* ML: 0
|
|
|
|
* BGR: 0/1 Depending on endian mode of the mcu?
|
|
|
|
* MH: 0
|
|
|
|
*/
|
|
|
|
|
2015-11-25 20:01:37 +01:00
|
|
|
#define ILI9341_MADCTL_RLANDSCAPE_MY ILI9341_MEMORY_ACCESS_CONTROL_MY
|
2014-10-20 23:19:43 +02:00
|
|
|
#define ILI9341_MADCTL_RLANDSCAPE_MX ILI9341_MEMORY_ACCESS_CONTROL_MX
|
|
|
|
#define ILI9341_MADCTL_RLANDSCAPE_MV ILI9341_MEMORY_ACCESS_CONTROL_MV
|
|
|
|
#define ILI9341_MADCTL_RLANDSCAPE_ML 0
|
|
|
|
#ifdef CONFIG_BIG_ENDIAN
|
|
|
|
# define ILI9341_MADCTL_RLANDSCAPE_BGR 0
|
|
|
|
#else
|
|
|
|
# define ILI9341_MADCTL_RLANDSCAPE_BGR ILI9341_MEMORY_ACCESS_CONTROL_BGR
|
|
|
|
#endif
|
|
|
|
#define ILI9341_MADCTL_RLANDSCAPE_MH 0
|
|
|
|
|
|
|
|
#define ILI9341_MADCTL_RLANDSCAPE_PARAM1 \
|
|
|
|
(ILI9341_MADCTL_RLANDSCAPE_MY | \
|
|
|
|
ILI9341_MADCTL_RLANDSCAPE_MX | \
|
|
|
|
ILI9341_MADCTL_RLANDSCAPE_MV | \
|
|
|
|
ILI9341_MADCTL_RLANDSCAPE_ML | \
|
|
|
|
ILI9341_MADCTL_RLANDSCAPE_BGR | \
|
|
|
|
ILI9341_MADCTL_RLANDSCAPE_MH)
|
|
|
|
|
2015-10-10 18:41:00 +02:00
|
|
|
/* RPortrait: 11000000 / 11001000 / hc8
|
2014-10-20 23:19:43 +02:00
|
|
|
*
|
|
|
|
* MY: 1
|
|
|
|
* MX: 1
|
|
|
|
* MV: 0
|
|
|
|
* ML: 0
|
|
|
|
* BGR: 0/1 Depending on endian mode of the mcu?
|
|
|
|
* MH: 0
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define ILI9341_MADCTL_RPORTRAIT_MY ILI9341_MEMORY_ACCESS_CONTROL_MY
|
2015-11-25 20:01:37 +01:00
|
|
|
#define ILI9341_MADCTL_RPORTRAIT_MX 0
|
2014-10-20 23:19:43 +02:00
|
|
|
#define ILI9341_MADCTL_RPORTRAIT_MV 0
|
2015-11-25 20:01:37 +01:00
|
|
|
#define ILI9341_MADCTL_RPORTRAIT_ML ILI9341_MEMORY_ACCESS_CONTROL_ML
|
2014-10-20 23:19:43 +02:00
|
|
|
#ifdef CONFIG_BIG_ENDIAN
|
|
|
|
# define ILI9341_MADCTL_RPORTRAIT_BGR 0
|
|
|
|
#else
|
|
|
|
# define ILI9341_MADCTL_RPORTRAIT_BGR ILI9341_MEMORY_ACCESS_CONTROL_BGR
|
|
|
|
#endif
|
|
|
|
#define ILI9341_MADCTL_RPORTRAIT_MH 0
|
|
|
|
|
|
|
|
#define ILI9341_MADCTL_RPORTRAIT_PARAM1 (ILI9341_MADCTL_RPORTRAIT_MY | \
|
|
|
|
ILI9341_MADCTL_RPORTRAIT_MX | \
|
|
|
|
ILI9341_MADCTL_RPORTRAIT_MV | \
|
|
|
|
ILI9341_MADCTL_RPORTRAIT_ML | \
|
|
|
|
ILI9341_MADCTL_RPORTRAIT_BGR | \
|
|
|
|
ILI9341_MADCTL_RPORTRAIT_MH)
|
|
|
|
|
|
|
|
/* Pixel Format Set (COLMOD)
|
|
|
|
*
|
|
|
|
* Note! RGB interface settings (DPI) is unimportant for the MCU interface
|
|
|
|
* mode but set the register to the defined state equal to the MCU interface
|
|
|
|
* pixel format.
|
|
|
|
*
|
|
|
|
* 16 Bit MCU: 01010101 / h55
|
|
|
|
*
|
|
|
|
* DPI: 5 (RGB16-565 RGB interface, not used)
|
|
|
|
* DBI: 5 (RGB16-565 MCU interface
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define ILI9341_PIXSET_16BITDPI ILI9341_PIXEL_FORMAT_SET_DPI(5)
|
|
|
|
#define ILI9341_PIXSET_16BITDBI ILI9341_PIXEL_FORMAT_SET_DBI(5)
|
|
|
|
|
|
|
|
#define ILI9341_PIXSET_16BITMCU_PARAM1 (ILI9341_PIXSET_16BITDPI | \
|
|
|
|
ILI9341_PIXSET_16BITDBI)
|
|
|
|
|
2015-10-10 18:41:00 +02:00
|
|
|
/* 18-bit MCU: 01100110 / h66 (not supported by nuttx until now)
|
2014-10-20 23:19:43 +02:00
|
|
|
*
|
|
|
|
* DPI: 6 (RGB18-666 RGB interface)
|
|
|
|
* DBI: 6 (RGB18-666 MCU interface)
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define ILI9341_PIXSET_18BITDPI ILI9341_PIXEL_FORMAT_SET_DPI(6)
|
|
|
|
#define ILI9341_PIXSET_18BITDBI ILI9341_PIXEL_FORMAT_SET_DBI(6)
|
|
|
|
|
|
|
|
#define ILI9341_PIXSET_18BITMCU_PARAM1 (ILI9341_PIXSET_18BITDPI | \
|
|
|
|
ILI9341_PIXSET_18BITDBI)
|
|
|
|
|
|
|
|
|
|
|
|
/* General fix display resolution */
|
|
|
|
|
|
|
|
#define ILI9341_XRES 240
|
|
|
|
#define ILI9341_YRES 320
|
|
|
|
|
|
|
|
|
|
|
|
/* Validate configuration */
|
|
|
|
|
|
|
|
#if CONFIG_LCD_ILI9341_NINTERFACES < 1
|
|
|
|
# undef CONFIG_LCD_ILI9341_IFACE0
|
|
|
|
#elif CONFIG_LCD_ILI9341_NINTERFACES < 2
|
|
|
|
# undef CONFIG_LCD_ILI9341_IFACE1
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
/* First LCD display */
|
|
|
|
|
|
|
|
#ifdef CONFIG_LCD_ILI9341_IFACE0
|
2015-09-08 18:21:19 +02:00
|
|
|
# if defined(CONFIG_LCD_ILI9341_IFACE0_LANDSCAPE)
|
2014-10-20 23:19:43 +02:00
|
|
|
# define ILI9341_IFACE0_ORIENT ILI9341_MADCTL_LANDSCAPE_PARAM1
|
|
|
|
# define ILI9341_IFACE0_STRIDE ILI9341_YRES
|
2015-09-08 18:21:19 +02:00
|
|
|
# elif defined(CONFIG_LCD_ILI9341_IFACE0_PORTRAIT)
|
2014-10-20 23:19:43 +02:00
|
|
|
# define ILI9341_IFACE0_ORIENT ILI9341_MADCTL_PORTRAIT_PARAM1
|
|
|
|
# define ILI9341_IFACE0_STRIDE ILI9341_XRES
|
2015-09-08 18:21:19 +02:00
|
|
|
# elif defined(CONFIG_LCD_ILI9341_IFACE0_RLANDSCAPE)
|
2014-10-20 23:19:43 +02:00
|
|
|
# define ILI9341_IFACE0_ORIENT ILI9341_MADCTL_RLANDSCAPE_PARAM1
|
|
|
|
# define ILI9341_IFACE0_STRIDE ILI9341_YRES
|
2015-09-08 18:21:19 +02:00
|
|
|
# elif defined(CONFIG_LCD_ILI9341_IFACE0_RPORTRAIT)
|
2014-10-20 23:19:43 +02:00
|
|
|
# define ILI9341_IFACE0_ORIENT ILI9341_MADCTL_RPORTRAIT_PARAM1
|
|
|
|
# define ILI9341_IFACE0_STRIDE ILI9341_XRES
|
|
|
|
# endif
|
|
|
|
# ifdef CONFIG_LCD_ILI9341_IFACE0_RGB565
|
|
|
|
# define ILI9341_IFACE0_PXFMT FB_FMT_RGB16_565
|
|
|
|
# define ILI9341_IFACE0_BPP 16
|
|
|
|
# define ILI9341_IFACE0_BUFFER ILI9341_IFACE0_STRIDE
|
|
|
|
# else
|
|
|
|
# error "undefined pixel format for lcd interface 0"
|
|
|
|
# endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Second LCD display */
|
|
|
|
|
|
|
|
#ifdef CONFIG_LCD_ILI9341_IFACE1
|
|
|
|
# ifdef CONFIG_LCD_ILI9341_IFACE1_LANDSCAPE
|
|
|
|
# define ILI9341_IFACE1_ORIENT ILI9341_MADCTL_LANDSCAPE_PARAM1
|
|
|
|
# define ILI9341_IFACE1_STRIDE ILI9341_YRES
|
|
|
|
# elif CONFIG_LCD_ILI9341_IFACE1_PORTRAIT
|
|
|
|
# define ILI9341_IFACE1_ORIENT ILI9341_MADCTL_PORTRAIT_PARAM1
|
|
|
|
# define ILI9341_IFACE1_STRIDE ILI9341_XRES
|
|
|
|
# elif CONFIG_LCD_ILI9341_IFACE1_RLANDSCAPE
|
|
|
|
# define ILI9341_IFACE1_ORIENT ILI9341_MADCTL_RLANDSCAPE_PARAM1
|
|
|
|
# define ILI9341_IFACE1_STRIDE ILI9341_YRES
|
|
|
|
# elif CONFIG_LCD_ILI9341_IFACE1_RPORTRAIT
|
|
|
|
# define ILI9341_IFACE1_ORIENT ILI9341_MADCTL_RPORTRAIT_PARAM1
|
|
|
|
# define ILI9341_IFACE1_STRIDE ILI9341_XRES
|
|
|
|
# endif
|
|
|
|
# ifdef CONFIG_LCD_ILI9341_IFACE1_RGB565
|
|
|
|
# define ILI9341_IFACE1_PXFMT FB_FMT_RGB16_565
|
|
|
|
# define ILI9341_IFACE1_BPP 16
|
|
|
|
# define ILI9341_IFACE1_BUFFER ILI9341_IFACE1_STRIDE
|
|
|
|
# else
|
|
|
|
# error "undefined pixel format for lcd interface 1"
|
|
|
|
# endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Add next LCD display */
|
|
|
|
|
|
|
|
/* Debug option */
|
|
|
|
|
|
|
|
#ifdef CONFIG_DEBUG_LCD
|
2016-06-11 23:50:49 +02:00
|
|
|
# define lcderr err
|
2016-06-11 19:59:51 +02:00
|
|
|
# define lcdinfo info
|
2014-10-20 23:19:43 +02:00
|
|
|
#else
|
2016-06-11 23:50:49 +02:00
|
|
|
# define lcderr(x...)
|
2016-06-11 19:59:51 +02:00
|
|
|
# define lcdinfo(x...)
|
2014-10-20 23:19:43 +02:00
|
|
|
#endif
|
|
|
|
|
2015-10-03 15:25:53 +02:00
|
|
|
/****************************************************************************
|
2014-10-20 23:19:43 +02:00
|
|
|
* Private Type Definition
|
2015-10-03 15:25:53 +02:00
|
|
|
****************************************************************************/
|
2014-10-20 23:19:43 +02:00
|
|
|
|
2015-10-10 18:41:00 +02:00
|
|
|
/* Each single connected ili9341 LCD driver needs an own driver instance
|
2014-10-20 23:19:43 +02:00
|
|
|
* to provide a unique getrun and putrun method. Also store fundamental
|
|
|
|
* parameter in driver internal structure. This minimal overhead should be
|
|
|
|
* acceptable.
|
|
|
|
*/
|
|
|
|
|
|
|
|
struct ili9341_dev_s
|
|
|
|
{
|
|
|
|
/* Publically visible device structure */
|
|
|
|
|
|
|
|
struct lcd_dev_s dev;
|
|
|
|
|
|
|
|
/* Private driver-specific information follows */
|
|
|
|
|
|
|
|
FAR struct ili9341_lcd_s *lcd;
|
|
|
|
|
|
|
|
/* Driver specific putrun function */
|
|
|
|
|
|
|
|
int (*putrun)(fb_coord_t row, fb_coord_t col,
|
|
|
|
FAR const uint8_t * buffer, size_t npixels);
|
|
|
|
#ifndef CONFIG_LCD_NOGETRUN
|
|
|
|
/* Driver specific getrun function */
|
|
|
|
|
|
|
|
int (*getrun)(fb_coord_t row, fb_coord_t col,
|
|
|
|
FAR uint8_t * buffer, size_t npixels);
|
|
|
|
#endif
|
|
|
|
/* Run buffer for the device */
|
|
|
|
|
|
|
|
uint16_t *runbuffer;
|
|
|
|
|
|
|
|
/* Display orientation, e.g. Landscape, Portrait */
|
|
|
|
|
|
|
|
uint8_t orient;
|
|
|
|
|
|
|
|
/* LCD driver pixel format */
|
|
|
|
|
|
|
|
uint8_t pxfmt;
|
|
|
|
|
|
|
|
/* LCD driver color depth */
|
|
|
|
|
|
|
|
uint8_t bpp;
|
|
|
|
|
|
|
|
/* Current power state of the device */
|
|
|
|
|
|
|
|
uint8_t power;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-10-03 15:25:53 +02:00
|
|
|
/****************************************************************************
|
2014-10-20 23:19:43 +02:00
|
|
|
* Private Function Protototypes
|
2015-10-03 15:25:53 +02:00
|
|
|
****************************************************************************/
|
2014-10-20 23:19:43 +02:00
|
|
|
|
|
|
|
/* Internal low level helpers */
|
|
|
|
|
|
|
|
static inline uint16_t ili9341_getxres(FAR struct ili9341_dev_s *dev);
|
|
|
|
static inline uint16_t ili9341_getyres(FAR struct ili9341_dev_s *dev);
|
|
|
|
|
|
|
|
/* lcd data transfer methods */
|
|
|
|
|
|
|
|
static int ili9341_putrun(int devno, fb_coord_t row, fb_coord_t col,
|
|
|
|
FAR const uint8_t * buffer, size_t npixels);
|
|
|
|
#ifndef CONFIG_LCD_NOGETRUN
|
|
|
|
static int ili9341_getrun(int devno, fb_coord_t row, fb_coord_t col,
|
|
|
|
FAR uint8_t * buffer, size_t npixels);
|
|
|
|
#endif
|
2015-10-10 18:41:00 +02:00
|
|
|
|
|
|
|
/* Definition of the public visible getrun / putrun methods
|
2014-10-20 23:19:43 +02:00
|
|
|
* each for a single LCD driver
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef CONFIG_LCD_ILI9341_IFACE0
|
|
|
|
static int ili9341_putrun0(fb_coord_t row, fb_coord_t col,
|
2015-10-10 18:41:00 +02:00
|
|
|
FAR const uint8_t *buffer, size_t npixsels);
|
2014-10-20 23:19:43 +02:00
|
|
|
#endif
|
|
|
|
#ifdef CONFIG_LCD_ILI9341_IFACE1
|
|
|
|
static int ili9341_putrun1(fb_coord_t row, fb_coord_t col,
|
|
|
|
FAR const uint8_t * buffer, size_t npixsels);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef CONFIG_LCD_NOGETRUN
|
|
|
|
# ifdef CONFIG_LCD_ILI9341_IFACE0
|
|
|
|
static int ili9341_getrun0(fb_coord_t row, fb_coord_t col,
|
|
|
|
FAR uint8_t * buffer, size_t npixsels);
|
|
|
|
# endif
|
|
|
|
# ifdef CONFIG_LCD_ILI9341_IFACE1
|
|
|
|
static int ili9341_getrun1(fb_coord_t row, fb_coord_t col,
|
|
|
|
FAR uint8_t * buffer, size_t npixsels);
|
|
|
|
# endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* lcd configuration */
|
|
|
|
|
|
|
|
static int ili9341_getvideoinfo(FAR struct lcd_dev_s *dev,
|
|
|
|
FAR struct fb_videoinfo_s *vinfo);
|
|
|
|
static int ili9341_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planeno,
|
|
|
|
FAR struct lcd_planeinfo_s *pinfo);
|
|
|
|
|
|
|
|
/* lcd specific controls */
|
|
|
|
|
|
|
|
static int ili9341_getpower(struct lcd_dev_s *dev);
|
|
|
|
static int ili9341_setpower(struct lcd_dev_s *dev, int power);
|
|
|
|
static int ili9341_getcontrast(struct lcd_dev_s *dev);
|
|
|
|
static int ili9341_setcontrast(struct lcd_dev_s *dev, unsigned int contrast);
|
|
|
|
|
2015-10-03 15:25:53 +02:00
|
|
|
/****************************************************************************
|
2014-10-20 23:19:43 +02:00
|
|
|
* Private Data
|
2015-10-03 15:25:53 +02:00
|
|
|
****************************************************************************/
|
2014-10-20 23:19:43 +02:00
|
|
|
|
|
|
|
/* Initialize driver instance 1 < LCD_ILI9341_NINTERFACES */
|
|
|
|
|
|
|
|
#ifdef CONFIG_LCD_ILI9341_IFACE0
|
|
|
|
static uint16_t g_runbuffer0[ILI9341_IFACE0_BUFFER];
|
|
|
|
#endif
|
|
|
|
#ifdef CONFIG_LCD_ILI9341_IFACE1
|
|
|
|
static uint16_t g_runbuffer1[ILI9341_IFACE1_BUFFER];
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static struct ili9341_dev_s g_lcddev[CONFIG_LCD_ILI9341_NINTERFACES] =
|
|
|
|
{
|
|
|
|
#ifdef CONFIG_LCD_ILI9341_IFACE0
|
|
|
|
{
|
|
|
|
.lcd = 0,
|
|
|
|
.putrun = ili9341_putrun0,
|
|
|
|
# ifndef CONFIG_LCD_NOGETRUN
|
|
|
|
.getrun = ili9341_getrun0,
|
|
|
|
# endif
|
|
|
|
.runbuffer = g_runbuffer0,
|
|
|
|
.orient = ILI9341_IFACE0_ORIENT,
|
|
|
|
.pxfmt = ILI9341_IFACE0_PXFMT,
|
|
|
|
.bpp = ILI9341_IFACE0_BPP,
|
|
|
|
.power = 0,
|
|
|
|
},
|
|
|
|
#endif
|
|
|
|
#ifdef CONFIG_LCD_ILI9341_IFACE1
|
|
|
|
{
|
|
|
|
.lcd = 0,
|
|
|
|
.putrun = ili9341_putrun1,
|
|
|
|
# ifndef CONFIG_LCD_NOGETRUN
|
|
|
|
.getrun = ili9341_getrun1,
|
|
|
|
# endif
|
|
|
|
.runbuffer = g_runbuffer1,
|
|
|
|
.orient = ILI9341_IFACE1_ORIENT,
|
|
|
|
.pxfmt = ILI9341_IFACE1_PXFMT,
|
|
|
|
.bpp = ILI9341_IFACE1_BPP,
|
|
|
|
.power = 0,
|
|
|
|
},
|
|
|
|
#endif
|
|
|
|
};
|
|
|
|
|
2015-10-03 15:25:53 +02:00
|
|
|
/****************************************************************************
|
2014-10-20 23:19:43 +02:00
|
|
|
* Private Functions
|
2015-10-03 15:25:53 +02:00
|
|
|
****************************************************************************/
|
2014-10-20 23:19:43 +02:00
|
|
|
|
2015-10-03 15:25:53 +02:00
|
|
|
/****************************************************************************
|
2014-10-20 23:19:43 +02:00
|
|
|
* Name: ili9341_getxres
|
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* Get horicontal resolution of the connected LCD driver depending on the
|
|
|
|
* configured display orientation.
|
|
|
|
*
|
|
|
|
* Parameters:
|
|
|
|
* dev - Reference to private driver structure
|
|
|
|
*
|
|
|
|
* Return Value:
|
|
|
|
*
|
|
|
|
* Horicontal resolution
|
|
|
|
*
|
2015-10-03 15:25:53 +02:00
|
|
|
****************************************************************************/
|
2014-10-20 23:19:43 +02:00
|
|
|
|
|
|
|
static inline uint16_t ili9341_getxres(FAR struct ili9341_dev_s *dev)
|
|
|
|
{
|
|
|
|
if (dev->orient == ILI9341_MADCTL_LANDSCAPE_PARAM1 ||
|
|
|
|
dev->orient == ILI9341_MADCTL_RLANDSCAPE_PARAM1)
|
|
|
|
{
|
|
|
|
return ILI9341_YRES;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ILI9341_XRES;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-10-03 15:25:53 +02:00
|
|
|
/****************************************************************************
|
2014-10-20 23:19:43 +02:00
|
|
|
* Name: ili9341_getyres
|
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* Get vertical resolution of the connected LCD driver depending on the
|
|
|
|
* configured display orientation.
|
|
|
|
*
|
|
|
|
* Parameter:
|
|
|
|
* dev - Reference to private driver structure
|
|
|
|
*
|
|
|
|
* Return Value:
|
|
|
|
*
|
|
|
|
* Vertical resolution
|
|
|
|
*
|
2015-10-03 15:25:53 +02:00
|
|
|
****************************************************************************/
|
2014-10-20 23:19:43 +02:00
|
|
|
|
|
|
|
static inline uint16_t ili9341_getyres(FAR struct ili9341_dev_s *dev)
|
|
|
|
{
|
|
|
|
if (dev->orient == ILI9341_MADCTL_LANDSCAPE_PARAM1 ||
|
|
|
|
dev->orient == ILI9341_MADCTL_RLANDSCAPE_PARAM1)
|
|
|
|
{
|
|
|
|
return ILI9341_XRES;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ILI9341_YRES;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-10-03 15:25:53 +02:00
|
|
|
/****************************************************************************
|
2014-10-20 23:19:43 +02:00
|
|
|
* Name: ili9341_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
|
|
|
|
*
|
2015-10-03 15:25:53 +02:00
|
|
|
****************************************************************************/
|
2014-10-20 23:19:43 +02:00
|
|
|
|
|
|
|
static void ili9341_selectarea(FAR struct ili9341_lcd_s *lcd,
|
|
|
|
uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1)
|
|
|
|
{
|
|
|
|
/* Select column */
|
|
|
|
|
|
|
|
lcd->sendcmd(lcd, ILI9341_COLUMN_ADDRESS_SET);
|
|
|
|
lcd->sendparam(lcd, (x0 >> 8));
|
|
|
|
lcd->sendparam(lcd, (x0 & 0xff));
|
|
|
|
lcd->sendparam(lcd, (x1 >> 8));
|
|
|
|
lcd->sendparam(lcd, (x1 & 0xff));
|
|
|
|
|
|
|
|
/* Select page */
|
|
|
|
|
|
|
|
lcd->sendcmd(lcd, ILI9341_PAGE_ADDRESS_SET);
|
|
|
|
lcd->sendparam(lcd, (y0 >> 8));
|
|
|
|
lcd->sendparam(lcd, (y0 & 0xff));
|
|
|
|
lcd->sendparam(lcd, (y1 >> 8));
|
|
|
|
lcd->sendparam(lcd, (y1 & 0xff));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-10-03 15:25:53 +02:00
|
|
|
/****************************************************************************
|
2014-10-20 23:19:43 +02:00
|
|
|
* Name: ili9341_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 writen 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
|
|
|
|
*
|
2015-10-03 15:25:53 +02:00
|
|
|
****************************************************************************/
|
2014-10-20 23:19:43 +02:00
|
|
|
|
|
|
|
static int ili9341_putrun(int devno, fb_coord_t row, fb_coord_t col,
|
|
|
|
FAR const uint8_t * buffer, size_t npixels)
|
|
|
|
{
|
|
|
|
FAR struct ili9341_dev_s *dev = &g_lcddev[devno];
|
|
|
|
FAR struct ili9341_lcd_s *lcd = dev->lcd;
|
2015-10-10 18:41:00 +02:00
|
|
|
FAR const uint16_t *src = (FAR const uint16_t *)buffer;
|
2014-10-20 23:19:43 +02:00
|
|
|
|
|
|
|
DEBUGASSERT(buffer && ((uintptr_t)buffer & 1) == 0);
|
|
|
|
|
|
|
|
/* Check if position outside of area */
|
|
|
|
if (col + npixels > ili9341_getxres(dev) || row > ili9341_getyres(dev))
|
|
|
|
{
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Select lcd driver */
|
|
|
|
|
|
|
|
lcd->select(lcd);
|
|
|
|
|
|
|
|
/* Select column and area similar to the partial raster line */
|
|
|
|
|
|
|
|
ili9341_selectarea(lcd, col, row, col + npixels - 1, row);
|
|
|
|
|
|
|
|
/* Send memory write cmd */
|
|
|
|
|
|
|
|
lcd->sendcmd(lcd, ILI9341_MEMORY_WRITE);
|
|
|
|
|
|
|
|
/* Send pixel to gram */
|
|
|
|
|
|
|
|
lcd->sendgram(lcd, src, npixels);
|
|
|
|
|
|
|
|
/* Deselect the lcd driver */
|
|
|
|
|
|
|
|
lcd->deselect(lcd);
|
|
|
|
|
|
|
|
return OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-10-03 15:25:53 +02:00
|
|
|
/****************************************************************************
|
2014-10-20 23:19:43 +02:00
|
|
|
* Name: ili9341_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
|
|
|
|
*
|
2015-10-03 15:25:53 +02:00
|
|
|
****************************************************************************/
|
2014-10-20 23:19:43 +02:00
|
|
|
|
|
|
|
# ifndef CONFIG_LCD_NOGETRUN
|
|
|
|
static int ili9341_getrun(int devno, fb_coord_t row, fb_coord_t col,
|
|
|
|
FAR uint8_t * buffer, size_t npixels)
|
|
|
|
{
|
|
|
|
FAR struct ili9341_dev_s *dev = &g_lcddev[devno];
|
|
|
|
FAR struct ili9341_lcd_s *lcd = dev->lcd;
|
2015-10-10 18:41:00 +02:00
|
|
|
FAR uint16_t *dest = (FAR uint16_t *)buffer;
|
2014-10-20 23:19:43 +02:00
|
|
|
|
|
|
|
DEBUGASSERT(buffer && ((uintptr_t)buffer & 1) == 0);
|
|
|
|
|
|
|
|
/* Check if position outside of area */
|
|
|
|
if (col + npixels > ili9341_getxres(dev) || row > ili9341_getyres(dev))
|
|
|
|
{
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Select lcd driver */
|
|
|
|
|
|
|
|
lcd->select(lcd);
|
|
|
|
|
|
|
|
/* Select column and area similar to the partial raster line */
|
|
|
|
|
|
|
|
ili9341_selectarea(lcd, col, row, col + npixels - 1, row);
|
|
|
|
|
|
|
|
/* Send memory read cmd */
|
|
|
|
|
|
|
|
lcd->sendcmd(lcd, ILI9341_MEMORY_READ);
|
|
|
|
|
|
|
|
/* Receive pixel to gram */
|
|
|
|
|
|
|
|
lcd->recvgram(lcd, dest, npixels);
|
|
|
|
|
|
|
|
/* Deselect the lcd driver */
|
|
|
|
|
|
|
|
lcd->deselect(lcd);
|
|
|
|
|
|
|
|
return OK;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2015-10-03 15:25:53 +02:00
|
|
|
/****************************************************************************
|
2014-10-20 23:19:43 +02:00
|
|
|
* Name: ili9341_hwinitialize
|
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* Initialize and configure the ILI9341 LCD driver hardware.
|
|
|
|
*
|
|
|
|
* Parameter:
|
|
|
|
* dev - A reference to the driver specific structure
|
|
|
|
*
|
|
|
|
* Returned Value:
|
|
|
|
*
|
|
|
|
* On success - OK
|
|
|
|
* On error - EINVAL
|
|
|
|
*
|
2015-10-03 15:25:53 +02:00
|
|
|
****************************************************************************/
|
2014-10-20 23:19:43 +02:00
|
|
|
|
|
|
|
static int ili9341_hwinitialize(FAR struct ili9341_dev_s *dev)
|
|
|
|
{
|
|
|
|
#ifdef CONFIG_DEBUG_LCD
|
|
|
|
uint8_t param;
|
|
|
|
#endif
|
|
|
|
FAR struct ili9341_lcd_s *lcd = dev->lcd;
|
|
|
|
|
|
|
|
/* Select spi device */
|
|
|
|
|
2016-06-11 23:50:49 +02:00
|
|
|
lcderr("Initialize lcd driver\n");
|
2014-10-20 23:19:43 +02:00
|
|
|
lcd->select(lcd);
|
|
|
|
|
|
|
|
#ifdef CONFIG_DEBUG_LCD
|
|
|
|
/* Read display identification */
|
|
|
|
|
|
|
|
lcd->sendcmd(lcd, ILI9341_READ_ID1);
|
|
|
|
lcd->recvparam(lcd, ¶m);
|
2016-06-11 23:50:49 +02:00
|
|
|
lcderr("ili9341 LCD driver: LCD modules manufacturer ID: %d\n", param);
|
2014-10-20 23:19:43 +02:00
|
|
|
lcd->sendcmd(lcd, ILI9341_READ_ID2);
|
|
|
|
lcd->recvparam(lcd, ¶m);
|
2016-06-11 23:50:49 +02:00
|
|
|
lcderr("ili9341 LCD driver: LCD modules driver version ID: %d\n", param);
|
2014-10-20 23:19:43 +02:00
|
|
|
lcd->sendcmd(lcd, ILI9341_READ_ID3);
|
|
|
|
lcd->recvparam(lcd, ¶m);
|
2016-06-11 23:50:49 +02:00
|
|
|
lcderr("ili9341 LCD driver: LCD modules driver ID: %d\n", param);
|
2014-10-20 23:19:43 +02:00
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Reset the lcd display to the default state */
|
|
|
|
|
2016-06-11 19:59:51 +02:00
|
|
|
lcdinfo("ili9341 LCD driver: Software Reset\n");
|
2014-10-20 23:19:43 +02:00
|
|
|
lcd->sendcmd(lcd, ILI9341_SOFTWARE_RESET);
|
|
|
|
up_mdelay(5);
|
|
|
|
|
2016-06-11 19:59:51 +02:00
|
|
|
lcdinfo("ili9341 LCD driver: set Memory Access Control: %04x\n", dev->orient);
|
2014-10-20 23:19:43 +02:00
|
|
|
lcd->sendcmd(lcd, ILI9341_MEMORY_ACCESS_CONTROL);
|
|
|
|
lcd->sendparam(lcd, dev->orient);
|
|
|
|
|
|
|
|
/* Select column and area */
|
|
|
|
|
|
|
|
ili9341_selectarea(lcd, 0, 0, ILI9341_XRES, ILI9341_YRES);
|
|
|
|
|
|
|
|
/* Pixel Format set */
|
|
|
|
|
|
|
|
lcd->sendcmd(lcd, ILI9341_PIXEL_FORMAT_SET);
|
|
|
|
|
|
|
|
/* 16 bit RGB565 */
|
|
|
|
|
2016-06-11 19:59:51 +02:00
|
|
|
lcdinfo("ili9341 LCD driver: Set Pixel Format: %04x\n",
|
2014-10-20 23:19:43 +02:00
|
|
|
ILI9341_PIXSET_16BITMCU_PARAM1);
|
|
|
|
lcd->sendparam(lcd, ILI9341_PIXSET_16BITMCU_PARAM1);
|
|
|
|
|
|
|
|
/* 18 bit RGB666, add settings here */
|
|
|
|
|
2016-06-11 19:59:51 +02:00
|
|
|
lcdinfo("ili9341 LCD driver: Set Interface control\n");
|
2014-10-20 23:19:43 +02:00
|
|
|
lcd->sendcmd(lcd, ILI9341_INTERFACE_CONTROL);
|
|
|
|
lcd->sendparam(lcd, ILI9341_IFCTL_PARAM1);
|
|
|
|
lcd->sendparam(lcd, ILI9341_IFCTL_PARAM2);
|
|
|
|
lcd->sendparam(lcd, ILI9341_IFCTL_PARAM3);
|
|
|
|
|
|
|
|
/* Sleep out */
|
|
|
|
|
2016-06-11 19:59:51 +02:00
|
|
|
lcdinfo("ili9341 LCD driver: Sleep Out\n");
|
2014-10-20 23:19:43 +02:00
|
|
|
lcd->sendcmd(lcd, ILI9341_SLEEP_OUT);
|
|
|
|
up_mdelay(120);
|
|
|
|
|
|
|
|
/* Deselect the device */
|
|
|
|
|
|
|
|
lcd->deselect(lcd);
|
|
|
|
|
|
|
|
/* Switch display off */
|
|
|
|
|
|
|
|
ili9341_setpower(&dev->dev, 0);
|
|
|
|
|
|
|
|
return OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-10-03 15:25:53 +02:00
|
|
|
/****************************************************************************
|
2014-10-20 23:19:43 +02:00
|
|
|
* Public Functions
|
2015-10-03 15:25:53 +02:00
|
|
|
****************************************************************************/
|
2014-10-20 23:19:43 +02:00
|
|
|
|
2015-10-03 15:25:53 +02:00
|
|
|
/****************************************************************************
|
2014-10-20 23:19:43 +02:00
|
|
|
* Name: ili9341_putrunx
|
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* Write a partial raster line to the LCD.
|
|
|
|
*
|
|
|
|
* Parameter:
|
|
|
|
* 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 writen 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
|
|
|
|
*
|
2015-10-03 15:25:53 +02:00
|
|
|
****************************************************************************/
|
2014-10-20 23:19:43 +02:00
|
|
|
|
|
|
|
#ifdef CONFIG_LCD_ILI9341_IFACE0
|
|
|
|
static int ili9341_putrun0(fb_coord_t row, fb_coord_t col,
|
|
|
|
FAR const uint8_t * buffer, size_t npixels)
|
|
|
|
{
|
|
|
|
return ili9341_putrun(0, row, col, buffer, npixels);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef CONFIG_LCD_ILI9341_IFACE1
|
|
|
|
static int ili9341_putrun1(fb_coord_t row, fb_coord_t col,
|
|
|
|
FAR const uint8_t * buffer, size_t npixels)
|
|
|
|
{
|
|
|
|
return ili9341_putrun(1, row, col, buffer, npixels);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2015-10-03 15:25:53 +02:00
|
|
|
/****************************************************************************
|
2014-10-20 23:19:43 +02:00
|
|
|
* Name: ili9341_getrunx
|
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* Read a partial raster line from the LCD.
|
|
|
|
*
|
|
|
|
* Parameter:
|
|
|
|
* row - Starting row to read from (range: 0 <= row < yres)
|
|
|
|
* col - Starting column to read from (range: 0 <= col <= xres-npixels)
|
|
|
|
* buffer - The buffer containing the run to be writen to the LCD
|
|
|
|
* npixels - The number of pixels to read from the
|
|
|
|
* (range: 0 < npixels <= xres-col)
|
|
|
|
*
|
|
|
|
* Returned Value:
|
|
|
|
*
|
|
|
|
* On success - OK
|
|
|
|
* On error - -EINVAL
|
|
|
|
*
|
2015-10-03 15:25:53 +02:00
|
|
|
****************************************************************************/
|
2014-10-20 23:19:43 +02:00
|
|
|
|
|
|
|
#ifndef CONFIG_LCD_NOGETRUN
|
|
|
|
# ifdef CONFIG_LCD_ILI9341_IFACE0
|
|
|
|
static int ili9341_getrun0(fb_coord_t row, fb_coord_t col,
|
|
|
|
FAR uint8_t * buffer, size_t npixels)
|
|
|
|
{
|
|
|
|
return ili9341_getrun(0, row, col, buffer, npixels);
|
|
|
|
}
|
|
|
|
# endif
|
|
|
|
|
|
|
|
# ifdef CONFIG_LCD_ILI9341_IFACE1
|
|
|
|
static int ili9341_getrun1(fb_coord_t row, fb_coord_t col,
|
|
|
|
FAR uint8_t * buffer, size_t npixels)
|
|
|
|
{
|
|
|
|
return ili9341_getrun(1, row, col, buffer, npixels);
|
|
|
|
}
|
|
|
|
# endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2015-10-03 15:25:53 +02:00
|
|
|
/****************************************************************************
|
2014-10-20 23:19:43 +02:00
|
|
|
* Name: ili9341_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
|
|
|
|
*
|
2015-10-03 15:25:53 +02:00
|
|
|
****************************************************************************/
|
2014-10-20 23:19:43 +02:00
|
|
|
|
|
|
|
static int ili9341_getvideoinfo(FAR struct lcd_dev_s *dev,
|
|
|
|
FAR struct fb_videoinfo_s *vinfo)
|
|
|
|
{
|
|
|
|
if (dev && vinfo)
|
|
|
|
{
|
|
|
|
FAR struct ili9341_dev_s *priv = (FAR struct ili9341_dev_s *)dev;
|
|
|
|
|
|
|
|
vinfo->fmt = priv->pxfmt;
|
|
|
|
vinfo->xres = ili9341_getxres(priv);
|
|
|
|
vinfo->yres = ili9341_getyres(priv);
|
|
|
|
vinfo->nplanes = 1;
|
|
|
|
|
2016-06-11 19:59:51 +02:00
|
|
|
lcdinfo("fmt: %d xres: %d yres: %d nplanes: %d\n",
|
2014-10-20 23:19:43 +02:00
|
|
|
vinfo->fmt, vinfo->xres, vinfo->yres, vinfo->nplanes);
|
|
|
|
|
|
|
|
return OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
2015-10-03 15:25:53 +02:00
|
|
|
/****************************************************************************
|
2014-10-20 23:19:43 +02:00
|
|
|
* Name: ili9341_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
|
|
|
|
*
|
2015-10-03 15:25:53 +02:00
|
|
|
****************************************************************************/
|
2014-10-20 23:19:43 +02:00
|
|
|
|
|
|
|
static int ili9341_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planeno,
|
|
|
|
FAR struct lcd_planeinfo_s *pinfo)
|
|
|
|
{
|
|
|
|
if (dev && pinfo && planeno == 0)
|
|
|
|
{
|
|
|
|
FAR struct ili9341_dev_s *priv = (FAR struct ili9341_dev_s *)dev;
|
|
|
|
|
|
|
|
pinfo->putrun = priv->putrun;
|
|
|
|
#ifndef CONFIG_LCD_NOGETRUN
|
|
|
|
pinfo->getrun = priv->getrun;
|
|
|
|
#endif
|
|
|
|
pinfo->bpp = priv->bpp;
|
2015-10-10 18:41:00 +02:00
|
|
|
pinfo->buffer = (FAR uint8_t *)priv->runbuffer; /* Run scratch buffer */
|
2014-10-20 23:19:43 +02:00
|
|
|
|
2016-06-11 19:59:51 +02:00
|
|
|
lcdinfo("planeno: %d bpp: %d\n", planeno, pinfo->bpp);
|
2014-10-20 23:19:43 +02:00
|
|
|
|
|
|
|
return OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
2015-10-03 15:25:53 +02:00
|
|
|
/****************************************************************************
|
2014-10-20 23:19:43 +02:00
|
|
|
* Name: ili9341_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
|
|
|
|
*
|
2015-10-03 15:25:53 +02:00
|
|
|
****************************************************************************/
|
2014-10-20 23:19:43 +02:00
|
|
|
|
|
|
|
static int ili9341_getpower(FAR struct lcd_dev_s *dev)
|
|
|
|
{
|
|
|
|
FAR struct ili9341_dev_s *priv = (FAR struct ili9341_dev_s *)dev;
|
|
|
|
|
|
|
|
if (priv)
|
|
|
|
{
|
2016-06-11 23:50:49 +02:00
|
|
|
lcderr("%d\n", priv->power);
|
2014-10-20 23:19:43 +02:00
|
|
|
|
|
|
|
return priv->power;
|
|
|
|
}
|
|
|
|
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
2015-10-03 15:25:53 +02:00
|
|
|
/****************************************************************************
|
2014-10-20 23:19:43 +02:00
|
|
|
* Name: ili9341_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
|
|
|
|
*
|
2015-10-03 15:25:53 +02:00
|
|
|
****************************************************************************/
|
2014-10-20 23:19:43 +02:00
|
|
|
|
|
|
|
static int ili9341_setpower(FAR struct lcd_dev_s *dev, int power)
|
|
|
|
{
|
|
|
|
FAR struct ili9341_dev_s *priv = (FAR struct ili9341_dev_s *)dev;
|
|
|
|
FAR struct ili9341_lcd_s *lcd = priv->lcd;
|
|
|
|
|
|
|
|
if (dev)
|
|
|
|
{
|
2016-06-11 23:50:49 +02:00
|
|
|
lcderr("%d\n", power);
|
2014-10-20 23:19:43 +02:00
|
|
|
|
|
|
|
lcd->select(lcd);
|
|
|
|
|
|
|
|
if (power > 0)
|
|
|
|
{
|
|
|
|
/* Set backlight level */
|
|
|
|
|
|
|
|
lcd->backlight(lcd, power);
|
|
|
|
|
|
|
|
/* And switch LCD on */
|
|
|
|
|
|
|
|
lcd->sendcmd(lcd, ILI9341_DISPLAY_ON);
|
|
|
|
up_mdelay(120);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Switch LCD off */
|
|
|
|
|
|
|
|
lcd->sendcmd(lcd, ILI9341_DISPLAY_OFF);
|
|
|
|
}
|
|
|
|
|
|
|
|
lcd->deselect(lcd);
|
|
|
|
|
|
|
|
priv->power = power;
|
|
|
|
|
|
|
|
return OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
2015-10-03 15:25:53 +02:00
|
|
|
/****************************************************************************
|
2014-10-20 23:19:43 +02:00
|
|
|
* Name: ili9341_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 ili9341.
|
|
|
|
*
|
2015-10-03 15:25:53 +02:00
|
|
|
****************************************************************************/
|
2014-10-20 23:19:43 +02:00
|
|
|
|
|
|
|
static int ili9341_getcontrast(struct lcd_dev_s *dev)
|
|
|
|
{
|
2016-06-11 19:59:51 +02:00
|
|
|
lcdinfo("Not implemented\n");
|
2014-10-20 23:19:43 +02:00
|
|
|
return -ENOSYS;
|
|
|
|
}
|
|
|
|
|
2015-10-03 15:25:53 +02:00
|
|
|
/****************************************************************************
|
2014-10-20 23:19:43 +02:00
|
|
|
* Name: ili9341_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 ili9341.
|
|
|
|
*
|
2015-10-03 15:25:53 +02:00
|
|
|
****************************************************************************/
|
2014-10-20 23:19:43 +02:00
|
|
|
|
|
|
|
static int ili9341_setcontrast(struct lcd_dev_s *dev, unsigned int contrast)
|
|
|
|
{
|
2016-06-11 19:59:51 +02:00
|
|
|
lcdinfo("contrast: %d\n", contrast);
|
2014-10-20 23:19:43 +02:00
|
|
|
return -ENOSYS;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-10-03 15:25:53 +02:00
|
|
|
/****************************************************************************
|
2014-10-20 23:19:43 +02:00
|
|
|
* Name: ili9341_initialize
|
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* Initialize the LCD video driver internal sturcture. Also initialize the
|
|
|
|
* lcd hardware if not done. The control of the LCD driver is depend on the
|
|
|
|
* selected MCU interface and part of the platform specific subdriver (see
|
|
|
|
* config/stm32f429i-disco/src/stm32_ili93414ws.c)
|
|
|
|
*
|
|
|
|
* Input Parameters:
|
|
|
|
*
|
|
|
|
* lcd - A reference to the platform specific driver instance to control the
|
|
|
|
* ili9341 display driver.
|
|
|
|
* devno - A value in the range of 0 through CONFIG_ILI9341_NINTERFACES-1.
|
|
|
|
* This allows support for multiple LCD devices.
|
|
|
|
*
|
|
|
|
* Returned Value:
|
|
|
|
*
|
|
|
|
* On success, this function returns a reference to the LCD driver object for
|
|
|
|
* the specified LCD driver. NULL is returned on any failure.
|
|
|
|
*
|
2015-10-03 15:25:53 +02:00
|
|
|
****************************************************************************/
|
2014-10-20 23:19:43 +02:00
|
|
|
|
|
|
|
FAR struct lcd_dev_s *ili9341_initialize(
|
|
|
|
FAR struct ili9341_lcd_s *lcd, int devno)
|
|
|
|
{
|
|
|
|
if (lcd && devno >= 0 && devno < CONFIG_LCD_ILI9341_NINTERFACES)
|
|
|
|
{
|
|
|
|
FAR struct ili9341_dev_s *priv = &g_lcddev[devno];
|
|
|
|
|
|
|
|
/* Check if initialized */
|
|
|
|
|
|
|
|
if (!priv->lcd)
|
|
|
|
{
|
|
|
|
FAR struct lcd_dev_s *dev = &priv->dev;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
/* Initialize internal structure */
|
|
|
|
|
|
|
|
dev->getvideoinfo = ili9341_getvideoinfo;
|
|
|
|
dev->getplaneinfo = ili9341_getplaneinfo;
|
|
|
|
dev->getpower = ili9341_getpower;
|
|
|
|
dev->setpower = ili9341_setpower;
|
|
|
|
dev->getcontrast = ili9341_getcontrast;
|
|
|
|
dev->setcontrast = ili9341_setcontrast;
|
|
|
|
priv->lcd = lcd;
|
|
|
|
|
|
|
|
/* Initialze the LCD driver */
|
|
|
|
|
|
|
|
ret = ili9341_hwinitialize(priv);
|
|
|
|
|
|
|
|
if (ret == OK)
|
|
|
|
{
|
|
|
|
return &priv->dev;
|
|
|
|
}
|
|
|
|
|
|
|
|
errno = EINVAL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-10-03 15:25:53 +02:00
|
|
|
/****************************************************************************
|
2014-10-20 23:19:43 +02:00
|
|
|
* Name: ili9341_clear
|
|
|
|
*
|
|
|
|
* Description:
|
|
|
|
* This is a non-standard LCD interface. Because of the various rotations,
|
|
|
|
* clearing the display in the normal way by writing a sequences of runs that
|
|
|
|
* covers the entire display can be very slow. Here the display is cleared by
|
|
|
|
* simply setting all GRAM memory to the specified color.
|
|
|
|
*
|
|
|
|
* Parameter:
|
|
|
|
* dev - A reference to the lcd driver structure
|
|
|
|
* color - The background color
|
|
|
|
*
|
|
|
|
* Returned Value:
|
|
|
|
*
|
|
|
|
* On success - OK
|
|
|
|
* On error - -EINVAL
|
|
|
|
*
|
2015-10-03 15:25:53 +02:00
|
|
|
****************************************************************************/
|
2014-10-20 23:19:43 +02:00
|
|
|
|
|
|
|
int ili9341_clear(FAR struct lcd_dev_s *dev, uint16_t color)
|
|
|
|
{
|
|
|
|
FAR struct ili9341_dev_s *priv = (FAR struct ili9341_dev_s *)dev;
|
|
|
|
FAR struct ili9341_lcd_s *lcd = priv->lcd;
|
|
|
|
uint16_t xres = ili9341_getxres(priv);
|
|
|
|
uint16_t yres = ili9341_getyres(priv);
|
|
|
|
uint32_t n;
|
|
|
|
|
|
|
|
if (!lcd)
|
|
|
|
{
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Select lcd driver */
|
|
|
|
|
|
|
|
lcd->select(lcd);
|
|
|
|
|
|
|
|
/* Select column and area similar to the visible area */
|
|
|
|
|
|
|
|
ili9341_selectarea(lcd, 0, 0, xres, yres);
|
|
|
|
|
|
|
|
/* Send memory write cmd */
|
|
|
|
|
|
|
|
lcd->sendcmd(lcd, ILI9341_MEMORY_WRITE);
|
|
|
|
|
|
|
|
/* clear the visible area */
|
|
|
|
|
|
|
|
for (n = 0; n < xres * yres; n++)
|
|
|
|
{
|
|
|
|
/* Send pixel to gram */
|
|
|
|
|
|
|
|
lcd->sendgram(lcd, &color, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Deselect the lcd driver */
|
|
|
|
|
|
|
|
lcd->deselect(lcd);
|
|
|
|
|
|
|
|
return OK;
|
|
|
|
}
|