You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ac...@apache.org on 2021/09/16 11:39:41 UTC
[incubator-nuttx] branch master updated: drivers/lcd: Add GC9A01
driver and refine ST7735
This is an automated email from the ASF dual-hosted git repository.
acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new a5406c6 drivers/lcd: Add GC9A01 driver and refine ST7735
a5406c6 is described below
commit a5406c63cb57686492cd052afd732db58e6a8c86
Author: Peter Bee <bi...@xiaomi.com>
AuthorDate: Thu Sep 16 11:55:39 2021 +0800
drivers/lcd: Add GC9A01 driver and refine ST7735
Added custom resolution, offset and BGR mode for ST7735 driver
Added GC9A01 driver (based on ST7789 driver)
Signed-off-by: Peter Bee <bi...@xiaomi.com>
---
drivers/lcd/Kconfig | 97 ++++++-
drivers/lcd/Make.defs | 4 +
drivers/lcd/{st7735.c => gc9a01.c} | 503 +++++++++++++++++++++++++------------
drivers/lcd/gc9a01.h | 71 ++++++
drivers/lcd/st7735.c | 95 +++++--
drivers/lcd/st7735.h | 11 +
include/nuttx/lcd/gc9a01.h | 72 ++++++
7 files changed, 668 insertions(+), 185 deletions(-)
diff --git a/drivers/lcd/Kconfig b/drivers/lcd/Kconfig
index bd8f6d6..58bbf4c 100644
--- a/drivers/lcd/Kconfig
+++ b/drivers/lcd/Kconfig
@@ -569,12 +569,52 @@ config LCD_ST7735
default n
if LCD_ST7735
- config LCD_ST7735_GM00
- bool "132x162 Display Resolution"
+ choice
+ prompt "LCD Preset Resolutions"
+ optional
+
+ config LCD_ST7735_GM11
+ bool "128x160"
+
+ config LCD_ST7735_GM00
+ bool "132x162"
+
+ config LCD_ST7735_GM01
+ bool "132x132"
+
+ endchoice
+
+if !LCD_ST7735_GM00 && !LCD_ST7735_GM01 && !LCD_ST7735_GM11
+
+ config LCD_ST7735_XRES
+ int "ST7735 X Resolution"
+ default 128
+ ---help---
+ Specifies the X resolution of the LCD.
+
+ config LCD_ST7735_YRES
+ int "ST7735 Y Resolution"
+ default 160
+ ---help---
+ Specifies the Y resolution of the LCD.
+
+ config LCD_ST7735_XOFFSET
+ int "ST7735 X Offset"
+ default 0
+ ---help---
+ Specifies the X offset of the LCD.
+
+ config LCD_ST7735_YOFFSET
+ int "ST7735 Y Offset"
+ default 0
+ ---help---
+ Specifies the Y offset of the LCD.
+
+endif
+
+ config LCD_ST7735_BGR
+ bool "Swap R & B channel"
default n
- ---help---
- Two resolutions are available, either the 132x162 or
- the 128x160
config LCD_ST7735_BPP
int "Bit Per Pixel (12, 16 or 18)"
@@ -633,6 +673,53 @@ if LCD_ST7789
endif # LCD_ST7789
+config LCD_GC9A01
+ bool "Galaxycore GC9A01 TFT Controller"
+ default n
+
+if LCD_GC9A01
+ config LCD_GC9A01_XRES
+ int "GC9A01 X Resolution"
+ default 240
+ ---help---
+ Specifies the X resolution of the LCD.
+
+ config LCD_GC9A01_YRES
+ int "GC9A01 Y Resolution"
+ default 240
+ ---help---
+ Specifies the Y resolution of the LCD.
+
+ config LCD_GC9A01_XOFFSET
+ int "GC9A01 X Offset"
+ default 0
+ ---help---
+ Specifies the X offset of the LCD.
+
+ config LCD_GC9A01_YOFFSET
+ int "GC9A01 Y Offset"
+ default 0
+ ---help---
+ Specifies the Y offset of the LCD.
+
+ config LCD_GC9A01_BGR
+ bool "Swap R & B channel"
+ default n
+
+ config LCD_GC9A01_BPP
+ int "Bit Per Pixel (12 or 16)"
+ default 16
+
+ config LCD_GC9A01_SPIMODE
+ int "SPI Mode"
+ default 0
+
+ config LCD_GC9A01_FREQUENCY
+ int "SPI Frequency"
+ default 1000000
+
+endif # LCD_GC9A01
+
config LCD_PCD8544
bool "Nokia 5110 LCD Display (Philips PCD8544)"
default n
diff --git a/drivers/lcd/Make.defs b/drivers/lcd/Make.defs
index 058c497..4f59a45 100644
--- a/drivers/lcd/Make.defs
+++ b/drivers/lcd/Make.defs
@@ -133,6 +133,10 @@ ifeq ($(CONFIG_LCD_ST7789),y)
CSRCS += st7789.c
endif
+ifeq ($(CONFIG_LCD_GC9A01),y)
+ CSRCS += gc9a01.c
+endif
+
endif # CONFIG_LCD
ifeq ($(CONFIG_SLCD),y)
diff --git a/drivers/lcd/st7735.c b/drivers/lcd/gc9a01.c
similarity index 50%
copy from drivers/lcd/st7735.c
copy to drivers/lcd/gc9a01.c
index e663409..6f8de70 100644
--- a/drivers/lcd/st7735.c
+++ b/drivers/lcd/gc9a01.c
@@ -1,5 +1,5 @@
/****************************************************************************
- * drivers/lcd/st7735.c
+ * drivers/lcd/gc9a01.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
@@ -35,11 +35,11 @@
#include <nuttx/arch.h>
#include <nuttx/spi/spi.h>
#include <nuttx/lcd/lcd.h>
-#include <nuttx/lcd/st7735.h>
+#include <nuttx/lcd/gc9a01.h>
-#include "st7735.h"
+#include "gc9a01.h"
-#ifdef CONFIG_LCD_ST7735
+#ifdef CONFIG_LCD_GC9A01
/****************************************************************************
* Pre-processor Definitions
@@ -47,14 +47,14 @@
/* Verify that all configuration requirements have been met */
-#ifndef CONFIG_LCD_ST7735_SPIMODE
-# define CONFIG_LCD_ST7735_SPIMODE SPIDEV_MODE0
+#ifndef CONFIG_LCD_GC9A01_SPIMODE
+# define CONFIG_LCD_GC9A01_SPIMODE SPIDEV_MODE0
#endif
/* SPI frequency */
-#ifndef CONFIG_LCD_ST7735_FREQUENCY
-# define CONFIG_LCD_ST7735_FREQUENCY 3000000
+#ifndef CONFIG_LCD_GC9A01_FREQUENCY
+# define CONFIG_LCD_GC9A01_FREQUENCY 1000000
#endif
/* Check contrast selection */
@@ -94,43 +94,43 @@
/* Display Resolution */
-#ifdef CONFIG_LCD_ST7735_GM00
-# define CONFIG_ST7735_XRES 132
-# define CONFIG_ST7735_YRES 162
-# define ST7735_LUT_SIZE 162
-#else
-# define CONFIG_ST7735_XRES 128
-# define CONFIG_ST7735_YRES 160
-# define ST7735_LUT_SIZE 160
+#if !defined(CONFIG_LCD_GC9A01_XRES)
+# define CONFIG_LCD_GC9A01_XRES 240
+#endif
+
+#if !defined(CONFIG_LCD_GC9A01_YRES)
+# define CONFIG_LCD_GC9A01_YRES 320
#endif
+#define GC9A01_LUT_SIZE CONFIG_LCD_GC9A01_YRES
+
#if defined(CONFIG_LCD_LANDSCAPE) || defined(CONFIG_LCD_RLANDSCAPE)
-# define ST7735_XRES CONFIG_ST7735_YRES
-# define ST7735_YRES CONFIG_ST7735_XRES
+# define GC9A01_XRES CONFIG_LCD_GC9A01_YRES
+# define GC9A01_YRES CONFIG_LCD_GC9A01_XRES
+# define GC9A01_XOFFSET CONFIG_LCD_GC9A01_YOFFSET
+# define GC9A01_YOFFSET CONFIG_LCD_GC9A01_XOFFSET
#else
-# define ST7735_XRES CONFIG_ST7735_XRES
-# define ST7735_YRES CONFIG_ST7735_YRES
+# define GC9A01_XRES CONFIG_LCD_GC9A01_XRES
+# define GC9A01_YRES CONFIG_LCD_GC9A01_YRES
+# define GC9A01_XOFFSET CONFIG_LCD_GC9A01_XOFFSET
+# define GC9A01_YOFFSET CONFIG_LCD_GC9A01_YOFFSET
#endif
/* Color depth and format */
-#ifdef CONFIG_LCD_ST7735_BPP
-# if (CONFIG_LCD_ST7735_BPP == 12)
-# define ST7735_BPP 12
-# define ST7735_COLORFMT FB_FMT_RGB12_444
-# define ST7735_BYTESPP 2
-# elif (CONFIG_LCD_ST7735_BPP == 16)
-# define ST7735_BPP 16
-# define ST7735_COLORFMT FB_FMT_RGB16_565
-# define ST7735_BYTESPP 2
-# elif (CONFIG_LCD_ST7735_BPP == 18)
-# define ST7735_BPP 18
-# define ST7735_COLORFMT FB_FMT_RGB16_666
-# define ST7735_BYTESPP 3
+#ifdef CONFIG_LCD_GC9A01_BPP
+# if (CONFIG_LCD_GC9A01_BPP == 12)
+# define GC9A01_BPP 12
+# define GC9A01_COLORFMT FB_FMT_RGB12_444
+# define GC9A01_BYTESPP 2
+# elif (CONFIG_LCD_GC9A01_BPP == 16)
+# define GC9A01_BPP 16
+# define GC9A01_COLORFMT FB_FMT_RGB16_565
+# define GC9A01_BYTESPP 2
# else
-# define ST7735_BPP 16
-# define ST7735_COLORFMT FB_FMT_RGB16_565
-# define ST7735_BYTESPP 2
+# define GC9A01_BPP 16
+# define GC9A01_COLORFMT FB_FMT_RGB16_565
+# define GC9A01_BYTESPP 2
# warning "Invalid color depth. Falling back to 16bpp"
# endif
#endif
@@ -141,7 +141,7 @@
/* This structure describes the state of this driver */
-struct st7735_dev_s
+struct gc9a01_dev_s
{
/* Publicly visible device structure */
@@ -165,7 +165,7 @@ struct st7735_dev_s
* buffers.
*/
- uint16_t runbuffer[ST7735_LUT_SIZE];
+ uint16_t runbuffer[GC9A01_LUT_SIZE];
};
/****************************************************************************
@@ -174,59 +174,68 @@ struct st7735_dev_s
/* Misc. Helpers */
-static void st7735_select(FAR struct spi_dev_s *spi, int bits);
-static void st7735_deselect(FAR struct spi_dev_s *spi);
-
-static inline void st7735_sendcmd(FAR struct st7735_dev_s *dev, uint8_t cmd);
-static void st7735_sleep(FAR struct st7735_dev_s *dev, bool sleep);
-static void st7735_display(FAR struct st7735_dev_s *dev, bool on);
-static void st7735_setarea(FAR struct st7735_dev_s *dev,
+static void gc9a01_select(FAR struct spi_dev_s *spi, int bits);
+static void gc9a01_deselect(FAR struct spi_dev_s *spi);
+
+static inline void gc9a01_sendcmd(FAR struct gc9a01_dev_s *dev, uint8_t cmd);
+static void gc9a01_cmddata(FAR struct gc9a01_dev_s *dev, uint8_t cmd,
+ const uint8_t *data, int len);
+static void gc9a01_init(FAR struct gc9a01_dev_s *dev);
+static void gc9a01_sleep(FAR struct gc9a01_dev_s *dev, bool sleep);
+static void gc9a01_setorientation(FAR struct gc9a01_dev_s *dev);
+static void gc9a01_display(FAR struct gc9a01_dev_s *dev, bool on);
+static void gc9a01_setarea(FAR struct gc9a01_dev_s *dev,
uint16_t x0, uint16_t y0,
uint16_t x1, uint16_t y1);
-static void st7735_bpp(FAR struct st7735_dev_s *dev, int bpp);
-static void st7735_wrram(FAR struct st7735_dev_s *dev,
+static void gc9a01_bpp(FAR struct gc9a01_dev_s *dev, int bpp);
+static void gc9a01_wrram(FAR struct gc9a01_dev_s *dev,
FAR const uint16_t *buff, size_t size);
-static void st7735_rdram(FAR struct st7735_dev_s *dev,
+#ifndef CONFIG_LCD_NOGETRUN
+static void gc9a01_rdram(FAR struct gc9a01_dev_s *dev,
FAR uint16_t *buff, size_t size);
-static void st7735_fill(FAR struct st7735_dev_s *dev, uint16_t color);
+#endif
+static void gc9a01_fill(FAR struct gc9a01_dev_s *dev, uint16_t color);
/* LCD Data Transfer Methods */
-static int st7735_putrun(fb_coord_t row, fb_coord_t col,
+static int gc9a01_putrun(fb_coord_t row, fb_coord_t col,
FAR const uint8_t *buffer, size_t npixels);
+static int gc9a01_putarea(fb_coord_t row_start, fb_coord_t row_end,
+ fb_coord_t col_start, fb_coord_t col_end,
+ FAR const uint8_t *buffer);
#ifndef CONFIG_LCD_NOGETRUN
-static int st7735_getrun(fb_coord_t row, fb_coord_t col,
+static int gc9a01_getrun(fb_coord_t row, fb_coord_t col,
FAR uint8_t *buffer, size_t npixels);
#endif
/* LCD Configuration */
-static int st7735_getvideoinfo(FAR struct lcd_dev_s *dev,
+static int gc9a01_getvideoinfo(FAR struct lcd_dev_s *dev,
FAR struct fb_videoinfo_s *vinfo);
-static int st7735_getplaneinfo(FAR struct lcd_dev_s *dev,
+static int gc9a01_getplaneinfo(FAR struct lcd_dev_s *dev,
unsigned int planeno,
FAR struct lcd_planeinfo_s *pinfo);
/* LCD Specific Controls */
-static int st7735_getpower(FAR struct lcd_dev_s *dev);
-static int st7735_setpower(FAR struct lcd_dev_s *dev, int power);
-static int st7735_getcontrast(FAR struct lcd_dev_s *dev);
-static int st7735_setcontrast(FAR struct lcd_dev_s *dev,
+static int gc9a01_getpower(FAR struct lcd_dev_s *dev);
+static int gc9a01_setpower(FAR struct lcd_dev_s *dev, int power);
+static int gc9a01_getcontrast(FAR struct lcd_dev_s *dev);
+static int gc9a01_setcontrast(FAR struct lcd_dev_s *dev,
unsigned int contrast);
/****************************************************************************
* Private Data
****************************************************************************/
-static struct st7735_dev_s g_lcddev;
+static struct gc9a01_dev_s g_lcddev;
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
- * Name: st7735_select
+ * Name: gc9a01_select
*
* Description:
* Select the SPI, locking and re-configuring if necessary
@@ -242,26 +251,26 @@ static struct st7735_dev_s g_lcddev;
*
****************************************************************************/
-static void st7735_select(FAR struct spi_dev_s *spi, int bits)
+static void gc9a01_select(FAR struct spi_dev_s *spi, int bits)
{
- /* Select ST7735 chip (locking the SPI bus in case there are multiple
+ /* Select GC9A01 chip (locking the SPI bus in case there are multiple
* devices competing for the SPI bus
*/
SPI_LOCK(spi, true);
SPI_SELECT(spi, SPIDEV_DISPLAY(0), true);
- /* Now make sure that the SPI bus is configured for the ST7735 (it
+ /* Now make sure that the SPI bus is configured for the GC9A01 (it
* might have gotten configured for a different device while unlocked)
*/
- SPI_SETMODE(spi, CONFIG_LCD_ST7735_SPIMODE);
+ SPI_SETMODE(spi, CONFIG_LCD_GC9A01_SPIMODE);
SPI_SETBITS(spi, bits);
- SPI_SETFREQUENCY(spi, CONFIG_LCD_ST7735_FREQUENCY);
+ SPI_SETFREQUENCY(spi, CONFIG_LCD_GC9A01_FREQUENCY);
}
/****************************************************************************
- * Name: st7735_deselect
+ * Name: gc9a01_deselect
*
* Description:
* De-select the SPI
@@ -276,96 +285,226 @@ static void st7735_select(FAR struct spi_dev_s *spi, int bits)
*
****************************************************************************/
-static void st7735_deselect(FAR struct spi_dev_s *spi)
+static void gc9a01_deselect(FAR struct spi_dev_s *spi)
{
- /* De-select ST7735 chip and relinquish the SPI bus. */
+ /* De-select GC9A01 chip and relinquish the SPI bus. */
SPI_SELECT(spi, SPIDEV_DISPLAY(0), false);
SPI_LOCK(spi, false);
}
/****************************************************************************
- * Name: st7735_sendcmd
+ * Name: gc9a01_sendcmd
*
* Description:
* Send a command to the driver.
*
****************************************************************************/
-static inline void st7735_sendcmd(FAR struct st7735_dev_s *dev, uint8_t cmd)
+static inline void gc9a01_sendcmd(FAR struct gc9a01_dev_s *dev, uint8_t cmd)
+{
+ gc9a01_select(dev->spi, 8);
+ SPI_CMDDATA(dev->spi, SPIDEV_DISPLAY(0), true);
+ SPI_SEND(dev->spi, cmd);
+ SPI_CMDDATA(dev->spi, SPIDEV_DISPLAY(0), false);
+ gc9a01_deselect(dev->spi);
+}
+
+/****************************************************************************
+ * Name: gc9a01_cmddata
+ *
+ * Description:
+ * Send a command and a series of data to the driver.
+ *
+ ****************************************************************************/
+
+static void gc9a01_cmddata(FAR struct gc9a01_dev_s *dev, uint8_t cmd,
+ const uint8_t *data, int len)
{
- st7735_select(dev->spi, 8);
+ gc9a01_select(dev->spi, 8);
SPI_CMDDATA(dev->spi, SPIDEV_DISPLAY(0), true);
SPI_SEND(dev->spi, cmd);
SPI_CMDDATA(dev->spi, SPIDEV_DISPLAY(0), false);
- st7735_deselect(dev->spi);
+ SPI_SNDBLOCK(dev->spi, data, len);
+ gc9a01_deselect(dev->spi);
}
/****************************************************************************
- * Name: st7735_sleep
+ * Name: gc9a01_init
+ *
+ * Description:
+ * Send gc9a01 internal init commands.
+ *
+ ****************************************************************************/
+
+static void gc9a01_init(FAR struct gc9a01_dev_s *dev)
+{
+ gc9a01_sendcmd(dev, GC9A01_SWRESET);
+ up_mdelay(120);
+ gc9a01_sendcmd(dev, GC9A01_ENIREG2);
+ gc9a01_cmddata(dev, 0xeb, (const uint8_t *) "\x14", 1);
+ gc9a01_sendcmd(dev, GC9A01_ENIREG1);
+ gc9a01_sendcmd(dev, GC9A01_ENIREG2);
+ gc9a01_cmddata(dev, 0xeb, (const uint8_t *) "\x14", 1);
+ gc9a01_cmddata(dev, 0x84, (const uint8_t *) "\x40", 1);
+ gc9a01_cmddata(dev, 0x85, (const uint8_t *) "\xFF", 1);
+ gc9a01_cmddata(dev, 0x86, (const uint8_t *) "\xFF", 1);
+ gc9a01_cmddata(dev, 0x87, (const uint8_t *) "\xFF", 1);
+ gc9a01_cmddata(dev, 0x88, (const uint8_t *) "\x0A", 1);
+ gc9a01_cmddata(dev, 0x89, (const uint8_t *) "\x21", 1);
+ gc9a01_cmddata(dev, 0x8a, (const uint8_t *) "\x00", 1);
+ gc9a01_cmddata(dev, 0x8b, (const uint8_t *) "\x80", 1);
+ gc9a01_cmddata(dev, 0x8c, (const uint8_t *) "\x01", 1);
+ gc9a01_cmddata(dev, 0x8d, (const uint8_t *) "\x01", 1);
+ gc9a01_cmddata(dev, 0x8e, (const uint8_t *) "\xFF", 1);
+ gc9a01_cmddata(dev, 0x8f, (const uint8_t *) "\xFF", 1);
+ gc9a01_cmddata(dev, 0xb6, (const uint8_t *) "\x00\x00", 2);
+ gc9a01_cmddata(dev, 0x3a, (const uint8_t *) "\x55", 1);
+ gc9a01_cmddata(dev, 0x90, (const uint8_t *) "\x08\x08\x08\x08", 4);
+ gc9a01_cmddata(dev, 0xbd, (const uint8_t *) "\x06", 1);
+ gc9a01_cmddata(dev, 0xbc, (const uint8_t *) "\x00", 1);
+ gc9a01_cmddata(dev, 0xff, (const uint8_t *) "\x60\x01\x04", 3);
+ gc9a01_cmddata(dev, 0xc3, (const uint8_t *) "\x13", 1);
+ gc9a01_cmddata(dev, 0xc4, (const uint8_t *) "\x13", 1);
+ gc9a01_cmddata(dev, 0xc9, (const uint8_t *) "\x22", 1);
+ gc9a01_cmddata(dev, 0xbe, (const uint8_t *) "\x11", 1);
+ gc9a01_cmddata(dev, 0xe1, (const uint8_t *) "\x10\x0E", 2);
+ gc9a01_cmddata(dev, 0xdf, (const uint8_t *) "\x21\x0c\x02", 3);
+ gc9a01_cmddata(dev, 0xf0, (const uint8_t *) "\x45\x09\x08\x08\x26\x2A", 6);
+ gc9a01_cmddata(dev, 0xf1, (const uint8_t *) "\x43\x70\x72\x36\x37\x6F", 6);
+ gc9a01_cmddata(dev, 0xf2, (const uint8_t *) "\x45\x09\x08\x08\x26\x2A", 6);
+ gc9a01_cmddata(dev, 0xf3, (const uint8_t *) "\x43\x70\x72\x36\x37\x6F", 6);
+ gc9a01_cmddata(dev, 0xed, (const uint8_t *) "\x1B\x0B", 2);
+ gc9a01_cmddata(dev, 0xae, (const uint8_t *) "\x77", 1);
+ gc9a01_cmddata(dev, 0xcd, (const uint8_t *) "\x63", 1);
+ gc9a01_cmddata(dev, 0x70, (const uint8_t *)
+ "\x07\x07\x04\x0E\x0F\x09\x07\x08\x03", 9);
+ gc9a01_cmddata(dev, 0xe8, (const uint8_t *) "\x34", 1);
+ gc9a01_cmddata(dev, 0x62, (const uint8_t *)
+ "\x18\x0D\x71\xED\x70\x70\x18\x0F\x71\xEF\x70\x70", 12);
+ gc9a01_cmddata(dev, 0x63, (const uint8_t *)
+ "\x18\x11\x71\xF1\x70\x70\x18\x13\x71\xF3\x70\x70", 12);
+ gc9a01_cmddata(dev, 0x64, (const uint8_t *)
+ "\x28\x29\xF1\x01\xF1\x00\x07", 7);
+ gc9a01_cmddata(dev, 0x66, (const uint8_t *)
+ "\x3C\x00\xCD\x67\x45\x45\x10\x00\x00\x00", 10);
+ gc9a01_cmddata(dev, 0x67, (const uint8_t *)
+ "\x00\x3C\x00\x00\x00\x01\x54\x10\x32\x98", 10);
+ gc9a01_cmddata(dev, 0x74, (const uint8_t *)
+ "\x10\x85\x80\x00\x00\x4E\x00", 7);
+ gc9a01_cmddata(dev, 0x98, (const uint8_t *) "\x3e\x07", 2);
+ gc9a01_sendcmd(dev, GC9A01_TEON);
+ up_mdelay(120);
+}
+
+/****************************************************************************
+ * Name: gc9a01_sleep
*
* Description:
* Sleep or wake up the driver.
*
****************************************************************************/
-static void st7735_sleep(FAR struct st7735_dev_s *dev, bool sleep)
+static void gc9a01_sleep(FAR struct gc9a01_dev_s *dev, bool sleep)
{
- st7735_sendcmd(dev, sleep ? ST7735_SLPIN : ST7735_SLPOUT);
+ gc9a01_sendcmd(dev, sleep ? GC9A01_SLPIN : GC9A01_SLPOUT);
up_mdelay(120);
}
/****************************************************************************
- * Name: st7735_display
+ * Name: gc9a01_display
*
* Description:
* Turn on or off the display.
*
****************************************************************************/
-static void st7735_display(FAR struct st7735_dev_s *dev, bool on)
+static void gc9a01_display(FAR struct gc9a01_dev_s *dev, bool on)
+{
+ gc9a01_sendcmd(dev, on ? GC9A01_DISPON : GC9A01_DISPOFF);
+ gc9a01_sendcmd(dev, GC9A01_INVON);
+}
+
+/****************************************************************************
+ * Name: gc9a01_setorientation
+ *
+ * Description:
+ * Set screen orientation.
+ *
+ ****************************************************************************/
+
+static void gc9a01_setorientation(FAR struct gc9a01_dev_s *dev)
{
- st7735_sendcmd(dev, on ? ST7735_DISPON : ST7735_DISPOFF);
+ uint8_t reg = GC9A01_MADCTL_MX;
+ gc9a01_sendcmd(dev, GC9A01_MADCTL);
+ gc9a01_select(dev->spi, 8);
+
+#if !defined(CONFIG_LCD_PORTRAIT) || defined(CONFIG_LCD_GC9A01_BGR)
+
+# if defined(CONFIG_LCD_RLANDSCAPE)
+
+ reg = GC9A01_MADCTL_MX | GC9A01_MADCTL_MY | GC9A01_MADCTL_MV;
+
+# elif defined(CONFIG_LCD_LANDSCAPE)
+
+ reg = GC9A01_MADCTL_MV;
+
+# elif defined(CONFIG_LCD_RPORTRAIT)
+
+ reg = GC9A01_MADCTL_MY;
+
+# endif
+
+# if defined(CONFIG_LCD_GC9A01_BGR)
+
+ reg |= GC9A01_MADCTL_BGR;
+
+# endif
+
+#endif
+
+ SPI_SEND(dev->spi, reg);
+ gc9a01_deselect(dev->spi);
}
/****************************************************************************
- * Name: st7735_setarea
+ * Name: gc9a01_setarea
*
* Description:
* Set the rectangular area for an upcoming read or write from RAM.
*
****************************************************************************/
-static void st7735_setarea(FAR struct st7735_dev_s *dev,
+static void gc9a01_setarea(FAR struct gc9a01_dev_s *dev,
uint16_t x0, uint16_t y0,
uint16_t x1, uint16_t y1)
{
/* Set row address */
- st7735_sendcmd(dev, ST7735_RASET);
- st7735_select(dev->spi, 16);
- SPI_SEND(dev->spi, y0);
- SPI_SEND(dev->spi, y1);
- st7735_deselect(dev->spi);
+ gc9a01_sendcmd(dev, GC9A01_RASET);
+ gc9a01_select(dev->spi, 16);
+ SPI_SEND(dev->spi, y0 + GC9A01_YOFFSET);
+ SPI_SEND(dev->spi, y1 + GC9A01_YOFFSET);
+ gc9a01_deselect(dev->spi);
/* Set column address */
- st7735_sendcmd(dev, ST7735_CASET);
- st7735_select(dev->spi, 16);
- SPI_SEND(dev->spi, x0);
- SPI_SEND(dev->spi, x1);
- st7735_deselect(dev->spi);
+ gc9a01_sendcmd(dev, GC9A01_CASET);
+ gc9a01_select(dev->spi, 16);
+ SPI_SEND(dev->spi, x0 + GC9A01_XOFFSET);
+ SPI_SEND(dev->spi, x1 + GC9A01_XOFFSET);
+ gc9a01_deselect(dev->spi);
}
/****************************************************************************
- * Name: st7735_bpp
+ * Name: gc9a01_bpp
*
* Description:
* Set the color depth of the device.
*
****************************************************************************/
-static void st7735_bpp(FAR struct st7735_dev_s *dev, int bpp)
+static void gc9a01_bpp(FAR struct gc9a01_dev_s *dev, int bpp)
{
uint8_t depth;
@@ -373,13 +512,11 @@ static void st7735_bpp(FAR struct st7735_dev_s *dev, int bpp)
if (dev->bpp != bpp)
{
- /* REVISIT: Works only for 12 and 16 bpp! */
-
- depth = bpp >> 2 | 1;
- st7735_sendcmd(dev, ST7735_COLMOD);
- st7735_select(dev->spi, 8);
+ depth = bpp / 2 - 3;
+ gc9a01_sendcmd(dev, GC9A01_COLMOD);
+ gc9a01_select(dev->spi, 8);
SPI_SEND(dev->spi, depth);
- st7735_deselect(dev->spi);
+ gc9a01_deselect(dev->spi);
/* Cache the new BPP */
@@ -388,68 +525,70 @@ static void st7735_bpp(FAR struct st7735_dev_s *dev, int bpp)
}
/****************************************************************************
- * Name: st7735_wrram
+ * Name: gc9a01_wrram
*
* Description:
* Write to the driver's RAM.
*
****************************************************************************/
-static void st7735_wrram(FAR struct st7735_dev_s *dev,
+static void gc9a01_wrram(FAR struct gc9a01_dev_s *dev,
FAR const uint16_t *buff, size_t size)
{
- st7735_sendcmd(dev, ST7735_RAMWR);
+ gc9a01_sendcmd(dev, GC9A01_RAMWR);
- st7735_select(dev->spi, ST7735_BYTESPP * 8);
+ gc9a01_select(dev->spi, GC9A01_BYTESPP * 8);
SPI_SNDBLOCK(dev->spi, buff, size);
- st7735_deselect(dev->spi);
+ gc9a01_deselect(dev->spi);
}
/****************************************************************************
- * Name: st7735_rdram
+ * Name: gc9a01_rdram
*
* Description:
* Read from the driver's RAM.
*
****************************************************************************/
-static void st7735_rdram(FAR struct st7735_dev_s *dev,
+#ifndef CONFIG_LCD_NOGETRUN
+static void gc9a01_rdram(FAR struct gc9a01_dev_s *dev,
FAR uint16_t *buff, size_t size)
{
- st7735_sendcmd(dev, ST7735_RAMRD);
+ gc9a01_sendcmd(dev, GC9A01_RAMRD);
- st7735_select(dev->spi, ST7735_BYTESPP * 8);
+ gc9a01_select(dev->spi, GC9A01_BYTESPP * 8);
SPI_RECVBLOCK(dev->spi, buff, size);
- st7735_deselect(dev->spi);
+ gc9a01_deselect(dev->spi);
}
+#endif
/****************************************************************************
- * Name: st7735_fill
+ * Name: gc9a01_fill
*
* Description:
* Fill the display with the specified color.
*
****************************************************************************/
-static void st7735_fill(FAR struct st7735_dev_s *dev, uint16_t color)
+static void gc9a01_fill(FAR struct gc9a01_dev_s *dev, uint16_t color)
{
int i;
- st7735_setarea(dev, 0, 0, ST7735_XRES - 1, ST7735_YRES - 1);
+ gc9a01_setarea(dev, 0, 0, GC9A01_XRES - 1, GC9A01_YRES - 1);
- st7735_sendcmd(dev, ST7735_RAMWR);
- st7735_select(dev->spi, ST7735_BYTESPP * 8);
+ gc9a01_sendcmd(dev, GC9A01_RAMWR);
+ gc9a01_select(dev->spi, GC9A01_BYTESPP *8);
- for (i = 0; i < ST7735_XRES * ST7735_YRES; i++)
+ for (i = 0; i < GC9A01_XRES * GC9A01_YRES; i++)
{
SPI_SEND(dev->spi, color);
}
- st7735_deselect(dev->spi);
+ gc9a01_deselect(dev->spi);
}
/****************************************************************************
- * Name: st7735_putrun
+ * Name: gc9a01_putrun
*
* Description:
* This method can be used to write a partial raster line to the LCD:
@@ -462,23 +601,57 @@ static void st7735_fill(FAR struct st7735_dev_s *dev, uint16_t color)
*
****************************************************************************/
-static int st7735_putrun(fb_coord_t row, fb_coord_t col,
+static int gc9a01_putrun(fb_coord_t row, fb_coord_t col,
FAR const uint8_t *buffer, size_t npixels)
{
- FAR struct st7735_dev_s *priv = &g_lcddev;
+ FAR struct gc9a01_dev_s *priv = &g_lcddev;
FAR const uint16_t *src = (FAR const uint16_t *)buffer;
ginfo("row: %d col: %d npixels: %d\n", row, col, npixels);
DEBUGASSERT(buffer && ((uintptr_t)buffer & 1) == 0);
- st7735_setarea(priv, col, row, col + npixels - 1, row);
- st7735_wrram(priv, src, npixels);
+ gc9a01_setarea(priv, col, row, col + npixels - 1, row);
+ gc9a01_wrram(priv, src, npixels);
return OK;
}
/****************************************************************************
- * Name: st7735_getrun
+ * Name: gc9a01_putarea
+ *
+ * Description:
+ * This method can be used to write a partial area to the LCD:
+ *
+ * row_start - Starting row to write to (range: 0 <= row < yres)
+ * row_end - Ending row to write to (range: row_start <= row < yres)
+ * col_start - Starting column to write to (range: 0 <= col <= xres)
+ * col_end - Ending column to write to
+ * (range: col_start <= col_end < xres)
+ * buffer - The buffer containing the area to be written to the LCD
+ *
+ ****************************************************************************/
+
+static int gc9a01_putarea(fb_coord_t row_start, fb_coord_t row_end,
+ fb_coord_t col_start, fb_coord_t col_end,
+ FAR const uint8_t *buffer)
+{
+ FAR struct gc9a01_dev_s *priv = &g_lcddev;
+ FAR const uint16_t *src = (FAR const uint16_t *)buffer;
+
+ ginfo("row_start: %d row_end: %d col_start: %d col_end: %d\n",
+ row_start, row_end, col_start, col_end);
+
+ DEBUGASSERT(buffer && ((uintptr_t)buffer & 1) == 0);
+
+ gc9a01_setarea(priv, col_start, row_start, col_end, row_end);
+ gc9a01_wrram(priv, src,
+ (row_end - row_start + 1) * (col_end - col_start + 1));
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: gc9a01_getrun
*
* Description:
* This method can be used to read a partial raster line from the LCD:
@@ -492,64 +665,65 @@ static int st7735_putrun(fb_coord_t row, fb_coord_t col,
****************************************************************************/
#ifndef CONFIG_LCD_NOGETRUN
-static int st7735_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer,
+static int gc9a01_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer,
size_t npixels)
{
- FAR struct st7735_dev_s *priv = &g_lcddev;
+ FAR struct gc9a01_dev_s *priv = &g_lcddev;
FAR uint16_t *dest = (FAR uint16_t *)buffer;
ginfo("row: %d col: %d npixels: %d\n", row, col, npixels);
DEBUGASSERT(buffer && ((uintptr_t)buffer & 1) == 0);
- st7735_setarea(priv, col, row, col + npixels - 1, row);
- st7735_rdram(priv, dest, npixels);
+ gc9a01_setarea(priv, col, row, col + npixels - 1, row);
+ gc9a01_rdram(priv, dest, npixels);
return OK;
}
#endif
/****************************************************************************
- * Name: st7735_getvideoinfo
+ * Name: gc9a01_getvideoinfo
*
* Description:
* Get information about the LCD video controller configuration.
*
****************************************************************************/
-static int st7735_getvideoinfo(FAR struct lcd_dev_s *dev,
+static int gc9a01_getvideoinfo(FAR struct lcd_dev_s *dev,
FAR struct fb_videoinfo_s *vinfo)
{
DEBUGASSERT(dev && vinfo);
lcdinfo("fmt: %d xres: %d yres: %d nplanes: 1\n",
- ST7735_COLORFMT, ST7735_XRES, ST7735_YRES);
+ GC9A01_COLORFMT, GC9A01_XRES, GC9A01_YRES);
- vinfo->fmt = ST7735_COLORFMT; /* Color format: RGB16-565: RRRR RGGG GGGB BBBB */
- vinfo->xres = ST7735_XRES; /* Horizontal resolution in pixel columns */
- vinfo->yres = ST7735_YRES; /* Vertical resolution in pixel rows */
+ vinfo->fmt = GC9A01_COLORFMT; /* Color format: RGB16-565: RRRR RGGG GGGB BBBB */
+ vinfo->xres = GC9A01_XRES; /* Horizontal resolution in pixel columns */
+ vinfo->yres = GC9A01_YRES; /* Vertical resolution in pixel rows */
vinfo->nplanes = 1; /* Number of color planes supported */
return OK;
}
/****************************************************************************
- * Name: st7735_getplaneinfo
+ * Name: gc9a01_getplaneinfo
*
* Description:
* Get information about the configuration of each LCD color plane.
*
****************************************************************************/
-static int st7735_getplaneinfo(FAR struct lcd_dev_s *dev,
+static int gc9a01_getplaneinfo(FAR struct lcd_dev_s *dev,
unsigned int planeno,
FAR struct lcd_planeinfo_s *pinfo)
{
- FAR struct st7735_dev_s *priv = (FAR struct st7735_dev_s *)dev;
+ FAR struct gc9a01_dev_s *priv = (FAR struct gc9a01_dev_s *)dev;
DEBUGASSERT(dev && pinfo && planeno == 0);
- lcdinfo("planeno: %d bpp: %d\n", planeno, ST7735_BPP);
+ lcdinfo("planeno: %d bpp: %d\n", planeno, GC9A01_BPP);
- pinfo->putrun = st7735_putrun; /* Put a run into LCD memory */
+ pinfo->putrun = gc9a01_putrun; /* Put a run into LCD memory */
+ pinfo->putarea = gc9a01_putarea; /* Put an area into LCD */
#ifndef CONFIG_LCD_NOGETRUN
- pinfo->getrun = st7735_getrun; /* Get a run from LCD memory */
+ pinfo->getrun = gc9a01_getrun; /* Get a run from LCD memory */
#endif
pinfo->buffer = (FAR uint8_t *)priv->runbuffer; /* Run scratch buffer */
pinfo->bpp = priv->bpp; /* Bits-per-pixel */
@@ -557,24 +731,24 @@ static int st7735_getplaneinfo(FAR struct lcd_dev_s *dev,
}
/****************************************************************************
- * Name: st7735_getpower
+ * Name: gc9a01_getpower
****************************************************************************/
-static int st7735_getpower(FAR struct lcd_dev_s *dev)
+static int gc9a01_getpower(FAR struct lcd_dev_s *dev)
{
- FAR struct st7735_dev_s *priv = (FAR struct st7735_dev_s *)dev;
+ FAR struct gc9a01_dev_s *priv = (FAR struct gc9a01_dev_s *)dev;
lcdinfo("power: %d\n", priv->power);
return priv->power;
}
/****************************************************************************
- * Name: st7735_setpower
+ * Name: gc9a01_setpower
****************************************************************************/
-static int st7735_setpower(FAR struct lcd_dev_s *dev, int power)
+static int gc9a01_setpower(FAR struct lcd_dev_s *dev, int power)
{
- FAR struct st7735_dev_s *priv = (FAR struct st7735_dev_s *)dev;
+ FAR struct gc9a01_dev_s *priv = (FAR struct gc9a01_dev_s *)dev;
lcdinfo("power: %d\n", power);
DEBUGASSERT((unsigned)power <= CONFIG_LCD_MAXPOWER);
@@ -585,7 +759,7 @@ static int st7735_setpower(FAR struct lcd_dev_s *dev, int power)
{
/* Turn on the display */
- st7735_display(priv, true);
+ gc9a01_display(priv, true);
/* Save the power */
@@ -595,7 +769,7 @@ static int st7735_setpower(FAR struct lcd_dev_s *dev, int power)
{
/* Turn off the display */
- st7735_display(priv, false);
+ gc9a01_display(priv, false);
/* Save the power */
@@ -606,28 +780,28 @@ static int st7735_setpower(FAR struct lcd_dev_s *dev, int power)
}
/****************************************************************************
- * Name: st7735_getcontrast
+ * Name: gc9a01_getcontrast
*
* Description:
* Get the current contrast setting (0-CONFIG_LCD_MAXCONTRAST).
*
****************************************************************************/
-static int st7735_getcontrast(FAR struct lcd_dev_s *dev)
+static int gc9a01_getcontrast(FAR struct lcd_dev_s *dev)
{
lcdinfo("Not implemented\n");
return -ENOSYS;
}
/****************************************************************************
- * Name: st7735_setcontrast
+ * Name: gc9a01_setcontrast
*
* Description:
* Set LCD panel contrast (0-CONFIG_LCD_MAXCONTRAST).
*
****************************************************************************/
-static int st7735_setcontrast(FAR struct lcd_dev_s *dev,
+static int gc9a01_setcontrast(FAR struct lcd_dev_s *dev,
unsigned int contrast)
{
lcdinfo("contrast: %d\n", contrast);
@@ -639,10 +813,10 @@ static int st7735_setcontrast(FAR struct lcd_dev_s *dev,
****************************************************************************/
/****************************************************************************
- * Name: st7735_initialize
+ * Name: gc9a01_initialize
*
* Description:
- * Initialize the ST7735 video hardware. The initial state of the
+ * Initialize the GC9A01 video hardware. The initial state of the
* LCD is fully initialized, display memory cleared, and the LCD ready
* to use, but with the power setting at 0 (full off == sleep mode).
*
@@ -653,29 +827,30 @@ static int st7735_setcontrast(FAR struct lcd_dev_s *dev,
*
****************************************************************************/
-FAR struct lcd_dev_s *st7735_lcdinitialize(FAR struct spi_dev_s *spi)
+FAR struct lcd_dev_s *gc9a01_lcdinitialize(FAR struct spi_dev_s *spi)
{
- FAR struct st7735_dev_s *priv = &g_lcddev;
+ FAR struct gc9a01_dev_s *priv = &g_lcddev;
/* Initialize the driver data structure */
- priv->dev.getvideoinfo = st7735_getvideoinfo;
- priv->dev.getplaneinfo = st7735_getplaneinfo;
- priv->dev.getpower = st7735_getpower;
- priv->dev.setpower = st7735_setpower;
- priv->dev.getcontrast = st7735_getcontrast;
- priv->dev.setcontrast = st7735_setcontrast;
+ priv->dev.getvideoinfo = gc9a01_getvideoinfo;
+ priv->dev.getplaneinfo = gc9a01_getplaneinfo;
+ priv->dev.getpower = gc9a01_getpower;
+ priv->dev.setpower = gc9a01_setpower;
+ priv->dev.getcontrast = gc9a01_getcontrast;
+ priv->dev.setcontrast = gc9a01_setcontrast;
priv->spi = spi;
/* Init the hardware and clear the display */
- st7735_sleep(priv, false);
- st7735_bpp(priv, ST7735_BPP);
- st7735_display(priv, true);
- st7735_fill(priv, 0xffff);
+ gc9a01_init(priv);
+ gc9a01_sleep(priv, false);
+ gc9a01_bpp(priv, GC9A01_BPP);
+ gc9a01_setorientation(priv);
+ gc9a01_display(priv, true);
+ gc9a01_fill(priv, 0xffff);
return &priv->dev;
}
-#endif /* CONFIG_LCD_ST7735 */
-
+#endif /* CONFIG_LCD_GC9A01 */
diff --git a/drivers/lcd/gc9a01.h b/drivers/lcd/gc9a01.h
new file mode 100644
index 0000000..858f9ad
--- /dev/null
+++ b/drivers/lcd/gc9a01.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+ * drivers/lcd/gc9a01.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __DRIVERS_LCD_GC9A01_H
+#define __DRIVERS_LCD_GC9A01_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define GC9A01_NOP 0x00 /* No Operation */
+#define GC9A01_SWRESET 0x01 /* Software Reset */
+#define GC9A01_RDDID 0x04 /* Read Display ID */
+#define GC9A01_RDDST 0x09 /* Read Display Status */
+
+#define GC9A01_SLPIN 0x10 /* Sleep In & Booster Off */
+#define GC9A01_SLPOUT 0x11 /* Sleep Out & Booster On */
+#define GC9A01_PTLON 0x12 /* Partial Mode On */
+#define GC9A01_NORON 0x13 /* Partial Mode Off */
+
+#define GC9A01_INVOFF 0x20 /* Display Inversion Off */
+#define GC9A01_INVON 0x21 /* Display Inversion On */
+#define GC9A01_DISPOFF 0x28 /* Display Off */
+#define GC9A01_DISPON 0x29 /* Display On */
+#define GC9A01_CASET 0x2a /* Column Address Set */
+#define GC9A01_RASET 0x2b /* Row Address Set */
+#define GC9A01_RAMWR 0x2c /* Memory Write */
+#define GC9A01_RAMRD 0x2e /* Memory Read */
+
+#define GC9A01_PTLAR 0x30 /* Partial Area */
+#define GC9A01_VSCRDEF 0x33 /* Vertical Scrolling Definition */
+#define GC9A01_TEON 0x35 /* Tering Effect Line On */
+#define GC9A01_MADCTL 0x36 /* Memory Data Access Control */
+
+#define GC9A01_MADCTL_MY (1<<7) /* Page Address Order */
+#define GC9A01_MADCTL_MX (1<<6) /* Column Address Order */
+#define GC9A01_MADCTL_MV (1<<5) /* Page/Column Order */
+#define GC9A01_MADCTL_ML (1<<4) /* Line Address Order */
+#define GC9A01_MADCTL_BGR (1<<3) /* Set Panel Order BGR */
+#define GC9A01_MADCTL_MH (1<<2) /* Display Data Latch Order */
+
+#define GC9A01_VSCSAD 0x37 /* Vertical Scrolling Start Address */
+#define GC9A01_IDMOFF 0x38 /* Idle Mode Off */
+#define GC9A01_IDMON 0x39 /* Idle Mode On */
+#define GC9A01_COLMOD 0x3a /* Interface Pixel Format */
+
+#define GC9A01_ENIREG1 0xFE /* Enable internal register 1 */
+#define GC9A01_ENIREG2 0xEF /* Enable internal register 2 */
+
+#endif /* __DRIVERS_LCD_GC9A01_H */
diff --git a/drivers/lcd/st7735.c b/drivers/lcd/st7735.c
index e663409..b3b7eed 100644
--- a/drivers/lcd/st7735.c
+++ b/drivers/lcd/st7735.c
@@ -45,6 +45,8 @@
* Pre-processor Definitions
****************************************************************************/
+#define MAX(a,b) ((a)>(b)?(a):(b))
+
/* Verify that all configuration requirements have been met */
#ifndef CONFIG_LCD_ST7735_SPIMODE
@@ -94,24 +96,37 @@
/* Display Resolution */
-#ifdef CONFIG_LCD_ST7735_GM00
-# define CONFIG_ST7735_XRES 132
-# define CONFIG_ST7735_YRES 162
-# define ST7735_LUT_SIZE 162
-#else
-# define CONFIG_ST7735_XRES 128
-# define CONFIG_ST7735_YRES 160
-# define ST7735_LUT_SIZE 160
+#if defined(CONFIG_LCD_ST7735_GM00)
+# define CONFIG_LCD_ST7735_XRES 132
+# define CONFIG_LCD_ST7735_YRES 162
+# define CONFIG_LCD_ST7735_XOFFSET 0
+# define CONFIG_LCD_ST7735_YOFFSET 0
+#elif defined(CONFIG_LCD_ST7735_GM01)
+# define CONFIG_LCD_ST7735_XRES 132
+# define CONFIG_LCD_ST7735_YRES 132
+# define CONFIG_LCD_ST7735_XOFFSET 0
+# define CONFIG_LCD_ST7735_YOFFSET 0
+#elif defined(CONFIG_LCD_ST7735_GM11)
+# define CONFIG_LCD_ST7735_XRES 128
+# define CONFIG_LCD_ST7735_YRES 160
+# define CONFIG_LCD_ST7735_XOFFSET 0
+# define CONFIG_LCD_ST7735_YOFFSET 0
#endif
#if defined(CONFIG_LCD_LANDSCAPE) || defined(CONFIG_LCD_RLANDSCAPE)
-# define ST7735_XRES CONFIG_ST7735_YRES
-# define ST7735_YRES CONFIG_ST7735_XRES
+# define ST7735_XRES CONFIG_LCD_ST7735_YRES
+# define ST7735_YRES CONFIG_LCD_ST7735_XRES
+# define ST7735_XOFFSET CONFIG_LCD_ST7735_YOFFSET
+# define ST7735_YOFFSET CONFIG_LCD_ST7735_XOFFSET
#else
-# define ST7735_XRES CONFIG_ST7735_XRES
-# define ST7735_YRES CONFIG_ST7735_YRES
+# define ST7735_XRES CONFIG_LCD_ST7735_XRES
+# define ST7735_YRES CONFIG_LCD_ST7735_YRES
+# define ST7735_XOFFSET CONFIG_LCD_ST7735_XOFFSET
+# define ST7735_YOFFSET CONFIG_LCD_ST7735_YOFFSET
#endif
+#define ST7735_LUT_SIZE MAX(CONFIG_LCD_ST7735_XRES, CONFIG_LCD_ST7735_YRES)
+
/* Color depth and format */
#ifdef CONFIG_LCD_ST7735_BPP
@@ -180,6 +195,7 @@ static void st7735_deselect(FAR struct spi_dev_s *spi);
static inline void st7735_sendcmd(FAR struct st7735_dev_s *dev, uint8_t cmd);
static void st7735_sleep(FAR struct st7735_dev_s *dev, bool sleep);
static void st7735_display(FAR struct st7735_dev_s *dev, bool on);
+static void st7735_setorientation(FAR struct st7735_dev_s *dev);
static void st7735_setarea(FAR struct st7735_dev_s *dev,
uint16_t x0, uint16_t y0,
uint16_t x1, uint16_t y1);
@@ -329,6 +345,52 @@ static void st7735_display(FAR struct st7735_dev_s *dev, bool on)
}
/****************************************************************************
+ * Name: st7735_setorientation
+ *
+ * Description:
+ * Set screen orientation.
+ *
+ ****************************************************************************/
+
+static void st7735_setorientation(FAR struct st7735_dev_s *dev)
+{
+ /* No need to change the orientation in PORTRAIT mode and RGB panel */
+
+#if !defined(CONFIG_LCD_PORTRAIT) || defined(CONFIG_LCD_ST7735_BGR)
+
+ uint8_t reg = 0x00;
+ st7735_sendcmd(dev, ST7735_MADCTL);
+ st7735_select(dev->spi, 8);
+
+# if defined(CONFIG_LCD_RLANDSCAPE)
+ /* RLANDSCAPE : MY=1 MV=1 */
+
+ reg = ST7735_MADCTL_MY | ST7735_MADCTL_MV;
+
+# elif defined(CONFIG_LCD_LANDSCAPE)
+ /* LANDSCAPE : MX=1 MV=1 */
+
+ reg = ST7735_MADCTL_MX | ST7735_MADCTL_MV;
+
+# elif defined(CONFIG_LCD_RPORTRAIT)
+ /* RPORTRAIT : MX=1 MY=1 */
+
+ reg = ST7735_MADCTL_MX | ST7735_MADCTL_MY;
+
+# endif
+
+# if defined(CONFIG_LCD_ST7735_BGR)
+
+ reg |= ST7735_MADCTL_BGR;
+
+# endif
+
+ SPI_SEND(dev->spi, reg);
+ st7735_deselect(dev->spi);
+#endif
+}
+
+/****************************************************************************
* Name: st7735_setarea
*
* Description:
@@ -344,16 +406,16 @@ static void st7735_setarea(FAR struct st7735_dev_s *dev,
st7735_sendcmd(dev, ST7735_RASET);
st7735_select(dev->spi, 16);
- SPI_SEND(dev->spi, y0);
- SPI_SEND(dev->spi, y1);
+ SPI_SEND(dev->spi, y0 + ST7735_YOFFSET);
+ SPI_SEND(dev->spi, y1 + ST7735_YOFFSET);
st7735_deselect(dev->spi);
/* Set column address */
st7735_sendcmd(dev, ST7735_CASET);
st7735_select(dev->spi, 16);
- SPI_SEND(dev->spi, x0);
- SPI_SEND(dev->spi, x1);
+ SPI_SEND(dev->spi, x0 + ST7735_XOFFSET);
+ SPI_SEND(dev->spi, x1 + ST7735_XOFFSET);
st7735_deselect(dev->spi);
}
@@ -671,6 +733,7 @@ FAR struct lcd_dev_s *st7735_lcdinitialize(FAR struct spi_dev_s *spi)
st7735_sleep(priv, false);
st7735_bpp(priv, ST7735_BPP);
+ st7735_setorientation(priv);
st7735_display(priv, true);
st7735_fill(priv, 0xffff);
diff --git a/drivers/lcd/st7735.h b/drivers/lcd/st7735.h
index d7cd525..057b2ff 100644
--- a/drivers/lcd/st7735.h
+++ b/drivers/lcd/st7735.h
@@ -46,8 +46,19 @@
#define ST7735_RASET 0x2b /* Row Address Set */
#define ST7735_RAMWR 0x2c /* Memory Write */
#define ST7735_RAMRD 0x2e /* Memory Read */
+#define ST7735_MADCTL 0x36 /* Memory Data Access Control */
+
+#define ST7735_MADCTL_MY (1<<7) /* Page Address Order */
+#define ST7735_MADCTL_MX (1<<6) /* Column Address Order */
+#define ST7735_MADCTL_MV (1<<5) /* Page/Column Order */
+#define ST7735_MADCTL_ML (1<<4) /* Line Address Order */
+#define ST7735_MADCTL_BGR (1<<3) /* Set Panel Order BGR */
+#define ST7735_MADCTL_MH (1<<2) /* Display Data Latch Order */
+
#define ST7735_IDMOFF 0x38 /* Idle Mode Off */
#define ST7735_IDMON 0x39 /* Idle Mode On */
#define ST7735_COLMOD 0x3a /* Interface Pixel Format */
+FAR struct lcd_dev_s *st7735_lcdinitialize(FAR struct spi_dev_s *spi);
+
#endif /* __DRIVERS_LCD_ST7735_H */
diff --git a/include/nuttx/lcd/gc9a01.h b/include/nuttx/lcd/gc9a01.h
new file mode 100644
index 0000000..6717eb1
--- /dev/null
+++ b/include/nuttx/lcd/gc9a01.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+ * include/nuttx/lcd/gc9a01.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __INCLUDE_NUTTX_GC9A01_H
+#define __INCLUDE_NUTTX_GC9A01_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <stdbool.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: gc9a01_initialize
+ *
+ * Description:
+ * Initialize the GC9A01 video hardware. The initial state of the
+ * LCD is fully initialized, display memory cleared, and the LCD ready
+ * to use, but with the power setting at 0 (full off == sleep mode).
+ *
+ * Returned Value:
+ *
+ * On success, this function returns a reference to the LCD object for
+ * the specified LCD. NULL is returned on any failure.
+ *
+ ****************************************************************************/
+
+FAR struct lcd_dev_s *gc9a01_lcdinitialize(FAR struct spi_dev_s *spi);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __INCLUDE_NUTTX_GC9A01_H */