diff options
Diffstat (limited to 'nuttx/drivers/lcd')
-rw-r--r-- | nuttx/drivers/lcd/Kconfig | 330 | ||||
-rw-r--r-- | nuttx/drivers/lcd/Make.defs | 76 | ||||
-rw-r--r-- | nuttx/drivers/lcd/README.txt | 189 | ||||
-rw-r--r-- | nuttx/drivers/lcd/mio283qt2.c | 1014 | ||||
-rw-r--r-- | nuttx/drivers/lcd/nokia6100.c | 1230 | ||||
-rw-r--r-- | nuttx/drivers/lcd/p14201.c | 1246 | ||||
-rw-r--r-- | nuttx/drivers/lcd/pcf8833.h | 152 | ||||
-rw-r--r-- | nuttx/drivers/lcd/s1d15g10.h | 141 | ||||
-rw-r--r-- | nuttx/drivers/lcd/sd1329.h | 527 | ||||
-rw-r--r-- | nuttx/drivers/lcd/skeleton.c | 401 | ||||
-rw-r--r-- | nuttx/drivers/lcd/ssd1289.c | 1380 | ||||
-rw-r--r-- | nuttx/drivers/lcd/ssd1289.h | 425 | ||||
-rw-r--r-- | nuttx/drivers/lcd/ssd1305.h | 211 | ||||
-rw-r--r-- | nuttx/drivers/lcd/ug-2864ambag01.c | 1161 | ||||
-rw-r--r-- | nuttx/drivers/lcd/ug-2864hsweg01.c | 1218 | ||||
-rw-r--r-- | nuttx/drivers/lcd/ug-9664hswag01.c | 1046 |
16 files changed, 0 insertions, 10747 deletions
diff --git a/nuttx/drivers/lcd/Kconfig b/nuttx/drivers/lcd/Kconfig deleted file mode 100644 index 2d20003ac..000000000 --- a/nuttx/drivers/lcd/Kconfig +++ /dev/null @@ -1,330 +0,0 @@ -# -# For a description of the syntax of this configuration file, -# see misc/tools/kconfig-language.txt. -# - -config LCD_NOGETRUN - bool "Write-only LCD" - default n - ---help--- - Many LCD hardware interfaces provide only minimal graphics capability. In - particulary, many simple LCD interfaces are write only. That is we, can - write graphics data to the LCD device memory, but we cannot read it back. - If the LCD hardware does not support reading the graphics memory, then - this option should be defined so that the NX layer can taking alternative - measures when the LCD is not readable. For example, if the LCD is not - readable, then NX will not attempt to support transparency. - - See also NX_WRITEONLY in the graphics support menu. - -config LCD_MAXCONTRAST - int "LCD maximum contrast" - default 63 if NOKIA6100_S1D15G10 - default 127 if NOKIA6100_PCF8833 - default 255 if LCD_P14201 - default 63 - ---help--- - must be 63 with the Epson controller and 127 with - the Phillips controller. - -config LCD_MAXPOWER - int "LCD maximum power" - default 1 - ---help--- - Maximum value of backlight setting. The backlight - control is managed outside of the 6100 driver so this value has no - meaning to the driver. Board-specific logic may place restrictions on - this value. - -config LCD_P14201 - bool "Rit P1402 series display" - default n - ---help--- - p14201.c. Driver for RiT P14201 series display with SD1329 IC - controller. This OLED is used with older versions of the - TI/Luminary LM3S8962 Evaluation Kit. - -if LCD_P14201 -config P14201_NINTERFACES - int "Number of physical P14201 devices" - default 1 - range 1,1 - ---help--- - Specifies the number of physical P14201 - devices that will be supported. - -config P14201_SPIMODE - int "SPI mode" - default 2 - range 0,3 - ---help--- - Controls the SPI mode - -config P14201_FREQUENCY - int "SPI frequency" - default 1000000 - ---help--- - Define to use a different bus frequency,FIXME DEFAULT VALUE OK? - -config P14201_FRAMEBUFFER - bool "Enable P14201 GDDRAM cache" - default y - ---help--- - If defined, accesses will be performed - using an in-memory copy of the OLEDs GDDRAM. This cost of this - buffer is 128 * 96 / 2 = 6Kb. If this is defined, then the driver - will be fully functional. If not, then it will have the following - limitations: - - Reading graphics memory cannot be supported, and - - All pixel writes must be aligned to byte boundaries. - The latter limitation effectively reduces the 128x96 disply to 64x96. -endif - -config LCD_NOKIA6100 - bool "Nokia 6100 display support" - default n - ---help--- - nokia6100.c. Supports the Nokia 6100 display with either the Philips - PCF883 or the Epson S1D15G10 display controller. This LCD is used - with the Olimex LPC1766-STK (but has not been fully integrated). -if LCD_NOKIA6100 -config NOKIA6100_NINTERFACES - int "Number of physical NOKIA6100 devices" - default 1 - range 1,1 - ---help--- - Specifies the number of physical Nokia - 6100 devices that will be supported. - -choice NOKIA6100_CONTROLLER - prompt "Controller Setup" - default NOKIA6100_S1D15G10 -config NOKIA6100_S1D15G10 - bool "S1D15G10 controller" - ---help--- - Selects the Epson S1D15G10 display controller - -config NOKIA6100_PCF8833 - bool "PCF8833 controller" - ---help--- - Selects the Phillips PCF8833 display controller -endchoice - -config NOKIA6100_SPIMODE - int "SPI mode" - default 0 - range 0,3 - ---help--- - Controls the SPI mode - -config NOKIA6100_FREQUENCY - int "SPI frequency" - default 1000000 - ---help--- - Define to use a different bus frequency - -config NOKIA6100_BLINIT - bool "Back light initial" - default n - ---help--- - Initial backlight setting - The following may need to be tuned for your hardware: - -config NOKIA6100_BPP - int "Display bits per pixel" - default 8 - ---help--- - Device supports 8, 12, and 16 bits per pixel. - -config NOKIA6100_INVERT - int "Display inversion" - default 1 - range 0,1 - ---help--- - Display inversion, 0 or 1, Default: 1 - -config NOKIA6100_MY - int "Display row direction" - default 0 - range 0,1 - ---help--- - Display row direction, 0 or 1, Default: 0 - -config NOKIA6100_MX - int "Display column direction" - default 1 - range 0,1 - ---help--- - Display column direction, 0 or 1, Default: 1 - -config NOKIA6100_V - int "Display address direction" - default 0 - range 0,1 - ---help--- - Display address direction, 0 or 1, Default: 0 - -config NOKIA6100_ML - int "Display scan direction" - default 0 - range 0,1 - ---help--- - Display scan direction, 0 or 1, Default: 0 - -config NOKIA6100_RGBORD - int "Display RGB order" - default 0 - range 0,1 - ---help--- - Display RGB order, 0 or 1, Default: 0 - Required LCD driver settings: -endif - -config LCD_UG9664HSWAG01 - bool "UG-9664HSWAG01 OLED Display Module" - default n - ---help--- - OLED Display Module, UG-9664HSWAG01, Univision Technology Inc. Used - with the LPCXpresso and Embedded Artists base board. - - Required LCD driver settings: - LCD_MAXCONTRAST should be 255, but any value >0 and <=255 will be accepted. - LCD_MAXPOWER should be 1: 0=off, 1=on - - Required SPI driver settings: - SPI_CMDDATA - Include support for cmd/data selection. - -if LCD_UG9664HSWAG01 - -config UG9664HSWAG01_SPIMODE - int "UG-9664HSWAG01 SPI Mode" - default 0 - ---help--- - Controls the SPI mode - -config UG9664HSWAG01_FREQUENCY - int "UG-9664HSWAG01 SPI Frequency" - default 3500000 - ---help--- - Define to use a different bus frequency - -config UG9664HSWAG01_NINTERFACES - int "Number of UG-9664HSWAG01 Devices" - default 1 - ---help--- - Specifies the number of physical UG-9664HSWAG01 devices that will be - supported. NOTE: At present, this must be undefined or defined to be 1. - -config UG9664HSWAG01_POWER - bool "Power control" - default n - ---help--- - If the hardware supports a controllable OLED a power supply, this - configuration should be defined. In this case the system must - provide an interface ug_power(). - -endif - -config LCD_UG2864AMBAG01 - bool "UG-2864AMBAG01 OLED Display Module" - default n - ---help--- - OLED Display Module, UG-2864AMBAG01, Univision Technology Inc. - - Required LCD driver settings: - LCD_MAXCONTRAST should be 255, but any value >0 and <=255 will be accepted. - LCD_MAXPOWER should be 1: 0=off, 1=on - - Required SPI driver settings: - SPI_CMDDATA - Include support for cmd/data selection. - -if LCD_UG2864AMBAG01 - - config UG2864AMBAG01_SPIMODE - int "UG-2864AMBAG01 SPI Mode" - default 3 - ---help--- - Controls the SPI mode - -config UG2864AMBAG01_FREQUENCY - int "UG-2864AMBAG01 SPI Frequency" - default 3500000 - ---help--- - Define to use a different bus frequency - -config UG2864AMBAG01_NINTERFACES - int "Number of UG-2864AMBAG01 Devices" - default 1 - ---help--- - Specifies the number of physical UG-9664HSWAG01 devices that will be - supported. NOTE: At present, this must be undefined or defined to be 1. - -endif - -config LCD_SSD1289 - bool "LCD Based on SSD1289 Controller" - default n - ---help--- - Enables generic support for any LCD based on the Solomon Systech, - Ltd, SSD1289 Controller. Use of this driver will usually require so - detailed customization of the LCD initialization code as necessary - for the specific LCD driven by the SSD1289 controller. - -if LCD_SSD1289 - -choice - prompt "SSD1289 Initialization Profile" - default SSD1289_PROFILE1 - -config SSD1289_PROFILE1 - bool "Profile 1" - -config SSD1289_PROFILE2 - bool "Profile 2" - -config SSD1289_PROFILE3 - bool "Profile 3" - -endchoice -endif - -choice - prompt "LCD Orientation" - default LCD_LANDSCAPE - depends on LCD - ---help--- - Some LCD drivers may support displays in different orientations. - If the LCD driver supports this capability, than these are configuration - options to select that display orientation. - -config LCD_LANDSCAPE - bool "Landscape orientation" - ---help--- - Define for "landscape" orientation support. Landscape mode refers one - of two orientations where the the display is wider than it is tall - (LCD_RLANDSCAPE is the other). This is the default orientation. - -config LCD_PORTRAIT - bool "Portrait orientation" - ---help--- - Define for "portrait" orientation support. Portrait mode refers one - of two orientations where the the display is taller than it is wide - (LCD_RPORTAIT is the other). - -config LCD_RPORTRAIT - bool "Reverse portrait display" - ---help--- - Define for "reverse portrait" orientation support. Reverse portrait mode - refers one of two orientations where the the display is taller than it is - wide (LCD_PORTAIT is the other). - -config LCD_RLANDSCAPE - bool "Reverse landscape orientation" - ---help--- - Define for "reverse landscape" orientation support. Reverse landscape mode - refers one of two orientations where the the display is wider than it is - tall (LCD_LANDSCAPE is the other). - -endchoice diff --git a/nuttx/drivers/lcd/Make.defs b/nuttx/drivers/lcd/Make.defs deleted file mode 100644 index 067f76f4e..000000000 --- a/nuttx/drivers/lcd/Make.defs +++ /dev/null @@ -1,76 +0,0 @@ -############################################################################ -# drivers/lcd/Make.defs -# -# Copyright (C) 2010-2012 Gregory Nutt. All rights reserved. -# Author: Gregory Nutt <gnutt@nuttx.org> -# -# 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 written 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. -# -############################################################################ - -# Don't build anything if there is no NX support for LCD drivers - -ifeq ($(CONFIG_NX_LCDDRIVER),y) - -# Include LCD drivers - -ifeq ($(CONFIG_LCD_P14201),y) - CSRCS += p14201.c -endif - -ifeq ($(CONFIG_LCD_NOKIA6100),y) - CSRCS += nokia6100.c -endif - -ifeq ($(CONFIG_LCD_UG2864AMBAG01),y) - CSRCS += ug-2864ambag01.c -endif - -ifeq ($(CONFIG_LCD_UG2864HSWEG01),y) - CSRCS += ug-2864hsweg01.c -endif - -ifeq ($(CONFIG_LCD_UG9664HSWAG01),y) - CSRCS += ug-9664hswag01.c -endif - -ifeq ($(CONFIG_LCD_SSD1289),y) - CSRCS += ssd1289.c -endif - -ifeq ($(CONFIG_LCD_MIO283QT2),y) - CSRCS += mio283qt2.c -endif - -# Include LCD driver build support - -DEPPATH += --dep-path lcd -VPATH += :lcd -CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)$(DELIM)drivers$(DELIM)lcd} -endif - diff --git a/nuttx/drivers/lcd/README.txt b/nuttx/drivers/lcd/README.txt deleted file mode 100644 index 0472043e6..000000000 --- a/nuttx/drivers/lcd/README.txt +++ /dev/null @@ -1,189 +0,0 @@ -nuttx/drivers/lcd README -======================== - -This is the README.txt file for the drivers/lcd/ directory. - -Contents -======== - - - LCD Header files - include/nuttx/lcd/lcd.h - struct lcd_dev_s - - Binding LCD Drivers - - Examples: /drivers/lcd/ - - Examples: configs/ - - graphics/ - -LCD Header files -================ - - include/nuttx/lcd/lcd.h - - Structures and APIs needed to work with LCD drivers are provided in - this header file. This header file also depends on some of the same - definitions used for the frame buffer driver as privided in - include/nuttx/fb.h. - - struct lcd_dev_s - - Each LCD device driver must implement an instance of struct lcd_dev_s. - That structure defines a call table with the following methods: - - - Get information about the LCD video controller configuration and the - configuration of each LCD color plane. - - int (*getvideoinfo)(FAR struct lcd_dev_s *dev, - FAR struct fb_videoinfo_s *vinfo); - int (*getplaneinfo)(FAR struct lcd_dev_s *dev, unsigned int planeno, - FAR struct lcd_planeinfo_s *pinfo); - - - The following are provided only if the video hardware supports RGB - color mapping: - - int (*getcmap)(FAR struct lcd_dev_s *dev, - FAR struct fb_cmap_s *cmap); - int (*putcmap)(FAR struct lcd_dev_s *dev, - FAR const struct fb_cmap_s *cmap); - - - The following are provided only if the video hardware supports a - hardware cursor: - - int (*getcursor)(FAR struct lcd_dev_s *dev, - FAR struct fb_cursorattrib_s *attrib); - int (*setcursor)(FAR struct lcd_dev_s *dev, - FAR struct fb_setcursor_s *settings); - - - 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. - - int (*getpower)(struct lcd_dev_s *dev); - - - Enable/disable LCD panel power (0: full off - CONFIG_LCD_MAXPOWER: - full on). On backlit LCDs, this setting may correspond to the - backlight setting. - - int (*setpower)(struct lcd_dev_s *dev, int power); - - - Get the current contrast setting (0-CONFIG_LCD_MAXCONTRAST) */ - - int (*getcontrast)(struct lcd_dev_s *dev); - - - Set LCD panel contrast (0-CONFIG_LCD_MAXCONTRAST) - - int (*setcontrast)(struct lcd_dev_s *dev, unsigned int contrast); - -Binding LCD Drivers -=================== - - LCD drivers are not normally directly accessed by user code, but are - usually bound to another, higher level device driver. In general, the - binding sequence is: - - 1. Get an instance of struct lcd_dev_s from the hardware-specific LCD - device driver, and - 2. Provide that instance to the initialization method of the higher - level device driver. - -Examples: /drivers/lcd/ -======================= - -Re-usable LCD drivers reside in the drivers/lcd directory: - - mio283qt2.c. This is a driver for the MI0283QT-2 LCD from Multi-Inno - Technology Co., Ltd. This LCD is based on the Himax HX8347-D LCD - controller. - - nokia6100.c. Supports the Nokia 6100 display with either the Philips - PCF883 or the Epson S1D15G10 display controller. This LCD is used - with the Olimex LPC1766-STK (but has not been fully integrated). - - p14201.c. Driver for RiT P14201 series display with SD1329 IC - controller. This OLED is used with older versions of the - TI/Luminary LM3S8962 Evaluation Kit. - - ssd12989.c. Generic LCD driver for LCDs based on the Solomon Systech - SSD1289 LCD controller. Think of this as a template for an LCD driver - that you will proably ahve to customize for any particular LCD - hardware. (see also configs/hymini-stm32v/src/ssd1289.c below). - - ug-9664hswag01.c. OLED Display Module, UG-9664HSWAG01", Univision - Technology Inc. Used with the LPC Xpresso and Embedded Artists - base board. - -Examples: configs/ -================== - -There are additional LCD drivers in the configs/<board>/src directory -that support additional LCDs. LCD drivers in the configuration directory -if they support some differ LCD interface (such as a parallel interface) -that makes then less re-usable: - - SSD1783 Drivers: - - configs/compal_e99/src/ssd1783.c - - SSD1289 Drivers: - - configs/hymini-stm32v/src/ssd1289.c. See also drivers/lcd/ssd1298.c - above. - configs/stm32f4discovery/src/up_ssd1289.c. This examples is the - bottom half for the SSD1289 driver at drivers/lcd/ssd1289.c - configs/hymini-stm32v/src/ssd1289.c. See also drivers/lcd/ssd1298.c - above. - configs/shenzhou/src/up_ssd1289.c - - kwikstik-k40: - - configs/kwikstik-k40/src/up_lcd.c. Don't waste your time. This is - just a stub. - - Nokia LCD Drivers: - - configs/olimex-lpc1766stk/src/up_lcd.c. This examples is the - bottom half for the driver at drivers/lcd/nokia6100.c. - This was never completedly debugged ... there are probably issues - with that nasty 9-bit SPI interfaces. - - HX8346: - - configs/sam3u-ek/src/up_lcd.c. The SAM3U-EK developement board features - a TFT/Transmissive color LCD module with touch-screen, FTM280C12D, - with integrated driver IC HX8346. - - HX8347: - - configs/pic32mx7mmb/src/up_mio283qt2.c. This driver is for the MI0283QT-2 - LCD from Multi-Inno Technology Co., Ltd. This LCD is based on the Himax - HX8347-D LCD controller. - - ILI93xx and Similar: - - configs/stm3210e-eval/src/up_lcd.c. This driver supports the following - LCDs: - - 1. Ampire AM-240320LTNQW00H - 2. Orise Tech SPFD5408B - 3. RenesasSP R61580 - - configs/stm3220g-eval/src/up_lcd.c and configs/stm3240g-eval/src/up_lcd.c. - AM-240320L8TNQW00H (LCD_ILI9320 or LCD_ILI9321) and - AM-240320D5TOQW01H (LCD_ILI9325) - configs/shenzhou/src/up_ili93xx.c. Another ILI93xx driver. - - OLEDs: - - configs/stm32f4discovery/src/up_ug2864ambag01.c - configs/stm32f4discovery/src/up_ug2864hsweg01.c - configs/zp214xpa/src/up_ug2864ambag01.c - - Alphnumeric LCD Displays: - - configs/skp16c26/src/up_lcd.c. Untested alphanumeric LCD driver. - configs/pcblogic-pic32/src/up_lcd1602.c - -graphics/ -========= - - See also the usage of the LCD driver in the graphics/ directory. - diff --git a/nuttx/drivers/lcd/mio283qt2.c b/nuttx/drivers/lcd/mio283qt2.c deleted file mode 100644 index 4c8835eef..000000000 --- a/nuttx/drivers/lcd/mio283qt2.c +++ /dev/null @@ -1,1014 +0,0 @@ -/************************************************************************************** - * drivers/lcd/mio283qt2.c - * - * This is a driver for the MI0283QT-2 LCD from Multi-Inno Technology Co., Ltd. This - * LCD is based on the Himax HX8347-D LCD controller. - * - * Copyright (C) 2012 Gregory Nutt. All rights reserved. - * Authors: Gregory Nutt <gnutt@nuttx.org> - * - * References: - * 1) LCD Module Specification, Model : MI0283QT-2, Multi-Inno Technology Co., - * Ltd., Revision 1.0 - * 2) Data Sheet: HX8347-D(T), 240RGB x 320 dot, 262K color, with internal GRAM, TFT - * Mobile Single Chip Driver Version 02 March, Doc No. HX8347-D(T)-DS, Himax - * Technologies, Inc., 2009, - * - * 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 written 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. - * - **************************************************************************************/ - -/************************************************************************************** - * Included Files - **************************************************************************************/ - -#include <nuttx/config.h> - -#include <sys/types.h> -#include <stdint.h> -#include <stdbool.h> -#include <string.h> -#include <errno.h> -#include <debug.h> - -#include <nuttx/arch.h> -#include <nuttx/spi.h> -#include <nuttx/lcd/lcd.h> -#include <nuttx/lcd/mio283qt2.h> - -#ifdef CONFIG_LCD_MIO283QT2 - -/************************************************************************************** - * Pre-processor Definitions - **************************************************************************************/ -/* Configuration **********************************************************************/ - -/* Check contrast selection */ - -#if !defined(CONFIG_LCD_MAXCONTRAST) -# define CONFIG_LCD_MAXCONTRAST 1 -#endif - -/* Check power setting */ - -#if !defined(CONFIG_LCD_MAXPOWER) || CONFIG_LCD_MAXPOWER < 1 -# define CONFIG_LCD_MAXPOWER 1 -#endif - -#if CONFIG_LCD_MAXPOWER > 255 -# error "CONFIG_LCD_MAXPOWER must be less than 256 to fit in uint8_t" -#endif - -/* Check orientation */ - -#if defined(CONFIG_LCD_PORTRAIT) -# if defined(CONFIG_LCD_LANDSCAPE) || defined(CONFIG_LCD_RLANDSCAPE) || defined(CONFIG_LCD_RPORTRAIT) -# error "Cannot define both portrait and any other orientations" -# endif -#elif defined(CONFIG_LCD_RPORTRAIT) -# if defined(CONFIG_LCD_LANDSCAPE) || defined(CONFIG_LCD_RLANDSCAPE) -# error "Cannot define both rportrait and any other orientations" -# endif -#elif defined(CONFIG_LCD_LANDSCAPE) -# ifdef CONFIG_LCD_RLANDSCAPE -# error "Cannot define both landscape and any other orientations" -# endif -#elif !defined(CONFIG_LCD_RLANDSCAPE) -# define CONFIG_LCD_LANDSCAPE 1 -#endif - -/* Define CONFIG_DEBUG_LCD to enable detailed LCD debug output. Verbose debug must - * also be enabled. - */ - -#ifndef CONFIG_DEBUG -# undef CONFIG_DEBUG_VERBOSE -# undef CONFIG_DEBUG_GRAPHICS -# undef CONFIG_DEBUG_LCD -#endif - -#ifndef CONFIG_DEBUG_VERBOSE -# undef CONFIG_DEBUG_LCD -#endif - -/* Display/Color Properties ***********************************************************/ -/* Display Resolution */ - -#if defined(CONFIG_LCD_LANDSCAPE) || defined(CONFIG_LCD_RLANDSCAPE) -# define MIO283QT2_XRES 320 -# define MIO283QT2_YRES 240 -#else -# define MIO283QT2_XRES 240 -# define MIO283QT2_YRES 320 -#endif - -/* Color depth and format */ - -#define MIO283QT2_BPP 16 -#define MIO283QT2_COLORFMT FB_FMT_RGB16_565 - -/* Hardware LCD/LCD controller definitions ********************************************/ -/* In this driver, I chose to use all literal constants for register address and - * values. Some recent experiences have shown me that during LCD bringup, it is more - * important to know the binary values rather than nice, people friendly names. Sad, - * but true. - */ - -#define HIMAX_ID 0x0047 - -/* LCD Profiles ***********************************************************************/ -/* Many details of the controller initialization must, unfortunately, vary from LCD to - * LCD. I have looked at the spec and at three different drivers for LCDs that have - * MIO283QT2 controllers. I have tried to summarize these differences as "LCD profiles" - * - * Most of the differences between LCDs are nothing more than a few minor bit - * settings. The most significant difference betwen LCD drivers in is the - * manner in which the LCD is powered up and in how the power controls are set. - * My suggestion is that if you have working LCD initialization code, you should - * simply replace the code in mio283qt2_hwinitialize with your working code. - */ - -#if defined (CONFIG_MIO283QT2_PROFILE2) -# undef MIO283QT2_USE_SIMPLE_INIT - - /* PWRCTRL1: AP=smalll-to-medium, DC=Flinex24, BT=+5/-4, DCT=Flinex24 */ - -# define PWRCTRL1_SETTING \ - (MIO283QT2_PWRCTRL1_AP_SMMED | MIO283QT2_PWRCTRL1_DC_FLINEx24 | \ - MIO283QT2_PWRCTRL1_BT_p5m4 | MIO283QT2_PWRCTRL1_DCT_FLINEx24) - - /* PWRCTRL2: 5.1v */ - -# define PWRCTRL2_SETTING MIO283QT2_PWRCTRL2_VRC_5p1V - - /* PWRCTRL3: x 2.165 - * NOTE: Many drivers have bit 8 set which is not defined in the MIO283QT2 spec. - */ - -# define PWRCTRL3_SETTING MIO283QT2_PWRCTRL3_VRH_x2p165 - - /* PWRCTRL4: VDV=9 + VCOMG */ - -# define PWRCTRL4_SETTING (MIO283QT2_PWRCTRL4_VDV(9) | MIO283QT2_PWRCTRL4_VCOMG) - - /* PWRCTRL5: VCM=56 + NOTP */ - -# define PWRCTRL5_SETTING (MIO283QT2_PWRCTRL5_VCM(56) | MIO283QT2_PWRCTRL5_NOTP) - -#elif defined (CONFIG_MIO283QT2_PROFILE3) -# undef MIO283QT2_USE_SIMPLE_INIT - - /* PWRCTRL1: AP=smalll-to-medium, DC=Flinex24, BT=+5/-4, DCT=Flinex24 */ - -# define PWRCTRL1_SETTING \ - (MIO283QT2_PWRCTRL1_AP_SMMED | MIO283QT2_PWRCTRL1_DC_FLINEx24 | \ - MIO283QT2_PWRCTRL1_BT_p5m4 | MIO283QT2_PWRCTRL1_DCT_FLINEx24) - - /* PWRCTRL2: 5.1v */ - -# define PWRCTRL2_SETTING MIO283QT2_PWRCTRL2_VRC_5p1V - - /* PWRCTRL3: x 2.165 - * NOTE: Many drivers have bit 8 set which is not defined in the MIO283QT2 spec. - */ - -# define PWRCTRL3_SETTING MIO283QT2_PWRCTRL3_VRH_x2p165 - - /* PWRCTRL4: VDV=9 + VCOMG */ - -# define PWRCTRL4_SETTING (MIO283QT2_PWRCTRL4_VDV(9) | MIO283QT2_PWRCTRL4_VCOMG) - - /* PWRCTRL5: VCM=56 + NOTP */ - -# define PWRCTRL5_SETTING (MIO283QT2_PWRCTRL5_VCM(56) | MIO283QT2_PWRCTRL5_NOTP) - -#else /* if defined (CONFIG_MIO283QT2_PROFILE1) */ -# undef MIO283QT2_USE_SIMPLE_INIT -# define MIO283QT2_USE_SIMPLE_INIT 1 - - /* PWRCTRL1: AP=medium-to-large, DC=Fosc/4, BT=+5/-4, DCT=Fosc/4 */ - -# define PWRCTRL1_SETTING \ - (MIO283QT2_PWRCTRL1_AP_MEDLG | MIO283QT2_PWRCTRL1_DC_FOSd4 | \ - MIO283QT2_PWRCTRL1_BT_p5m4 | MIO283QT2_PWRCTRL1_DCT_FOSd4) - - /* PWRCTRL2: 5.3v */ - -# define PWRCTRL2_SETTING MIO283QT2_PWRCTRL2_VRC_5p3V - - /* PWRCTRL3: x 2.570 - * NOTE: Many drivers have bit 8 set which is not defined in the MIO283QT2 spec. - */ - -# define PWRCTRL3_SETTING MIO283QT2_PWRCTRL3_VRH_x2p570 - - /* PWRCTRL4: VDV=12 + VCOMG */ - -# define PWRCTRL4_SETTING (MIO283QT2_PWRCTRL4_VDV(12) | MIO283QT2_PWRCTRL4_VCOMG) - - /* PWRCTRL5: VCM=60 + NOTP */ - -# define PWRCTRL5_SETTING (MIO283QT2_PWRCTRL5_VCM(60) | MIO283QT2_PWRCTRL5_NOTP) - -#endif - -/* Debug ******************************************************************************/ - -#ifdef CONFIG_DEBUG_LCD -# define lcddbg dbg -# define lcdvdbg vdbg -#else -# define lcddbg(x...) -# define lcdvdbg(x...) -#endif - -/************************************************************************************** - * Private Type Definition - **************************************************************************************/ - -/* This structure describes the state of this driver */ - -struct mio283qt2_dev_s -{ - /* Publically visible device structure */ - - struct lcd_dev_s dev; - - /* Private LCD-specific information follows */ - - FAR struct mio283qt2_lcd_s *lcd; /* The contained platform-specific, LCD interface */ - uint8_t power; /* Current power setting */ - - /* This is working memory allocated by the LCD driver for each LCD device - * and for each color plane. This memory will hold one raster line of data. - * The size of the allocated run buffer must therefore be at least - * (bpp * xres / 8). Actual alignment of the buffer must conform to the - * bitwidth of the underlying pixel type. - * - * If there are multiple planes, they may share the same working buffer - * because different planes will not be operate on concurrently. However, - * if there are multiple LCD devices, they must each have unique run buffers. - */ - - uint16_t runbuffer[MIO283QT2_XRES]; -}; - -/************************************************************************************** - * Private Function Protototypes - **************************************************************************************/ -/* Low Level LCD access */ - -static void mio283qt2_putreg(FAR struct mio283qt2_lcd_s *lcd, uint8_t regaddr, - uint16_t regval); -#ifndef CONFIG_LCD_NOGETRUN -static uint16_t mio283qt2_readreg(FAR struct mio283qt2_lcd_s *lcd, uint8_t regaddr); -#endif -static inline void mio283qt2_gramwrite(FAR struct mio283qt2_lcd_s *lcd, - uint16_t rgbcolor); -#ifndef CONFIG_LCD_NOGETRUN -static inline void mio283qt2_readsetup(FAR struct mio283qt2_lcd_s *lcd, - FAR uint16_t *accum); -static inline uint16_t mio283qt2_gramread(FAR struct mio283qt2_lcd_s *lcd, - FAR uint16_t *accum); -#endif -static void mio283qt2_setarea(FAR struct mio283qt2_lcd_s *lcd, - uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1); - -/* LCD Data Transfer Methods */ - -static int mio283qt2_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer, - size_t npixels); -static int mio283qt2_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer, - size_t npixels); - -/* LCD Configuration */ - -static int mio283qt2_getvideoinfo(FAR struct lcd_dev_s *dev, - FAR struct fb_videoinfo_s *vinfo); -static int mio283qt2_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planeno, - FAR struct lcd_planeinfo_s *pinfo); - -/* LCD RGB Mapping */ - -#ifdef CONFIG_FB_CMAP -# error "RGB color mapping not supported by this driver" -#endif - -/* Cursor Controls */ - -#ifdef CONFIG_FB_HWCURSOR -# error "Cursor control not supported by this driver" -#endif - -/* LCD Specific Controls */ - -static int mio283qt2_getpower(FAR struct lcd_dev_s *dev); -static int mio283qt2_setpower(FAR struct lcd_dev_s *dev, int power); -static int mio283qt2_getcontrast(FAR struct lcd_dev_s *dev); -static int mio283qt2_setcontrast(FAR struct lcd_dev_s *dev, unsigned int contrast); - -/* Initialization */ - -static inline int mio283qt2_hwinitialize(FAR struct mio283qt2_dev_s *priv); - -/************************************************************************************** - * Private Data - **************************************************************************************/ - -/* This driver can support only a signal MIO283QT2 device. This is due to an - * unfortunate decision made whent he getrun and putrun methods were designed. The - * following is the single MIO283QT2 driver state instance: - */ - -static struct mio283qt2_dev_s g_lcddev; - -/************************************************************************************** - * Private Functions - **************************************************************************************/ - -/************************************************************************************** - * Name: mio283qt2_putreg(lcd, - * - * Description: - * Write to an LCD register - * - **************************************************************************************/ - -static void mio283qt2_putreg(FAR struct mio283qt2_lcd_s *lcd, - uint8_t regaddr, uint16_t regval) -{ - /* Set the index register to the register address and write the register contents */ - - lcd->index(lcd, regaddr); - lcd->write(lcd, regval); -} - -/************************************************************************************** - * Name: mio283qt2_readreg - * - * Description: - * Read from an LCD register - * - **************************************************************************************/ - -#ifndef CONFIG_LCD_NOGETRUN -static uint16_t mio283qt2_readreg(FAR struct mio283qt2_lcd_s *lcd, uint8_t regaddr) -{ - /* Set the index register to the register address and read the register contents. */ - - lcd->index(lcd, regaddr); - return lcd->read(lcd); -} -#endif - -/************************************************************************************** - * Name: mio283qt2_gramselect - * - * Description: - * Setup to read or write multiple pixels to the GRAM memory - * - **************************************************************************************/ - -static inline void mio283qt2_gramselect(FAR struct mio283qt2_lcd_s *lcd) -{ - lcd->index(lcd, 0x22); -} - -/************************************************************************************** - * Name: mio283qt2_gramwrite - * - * Description: - * Setup to read or write multiple pixels to the GRAM memory - * - **************************************************************************************/ - -static inline void mio283qt2_gramwrite(FAR struct mio283qt2_lcd_s *lcd, uint16_t data) -{ - lcd->write(lcd, data); -} - -/************************************************************************************** - * Name: mio283qt2_readsetup - * - * Description: - * Prime the operation by reading one pixel from the GRAM memory if necessary for - * this LCD type. When reading 16-bit gram data, there may be some shifts in the - * returned data: - * - * - ILI932x: Discard first dummy read; no shift in the return data - * - **************************************************************************************/ - -#ifndef CONFIG_LCD_NOGETRUN -static inline void mio283qt2_readsetup(FAR struct mio283qt2_lcd_s *lcd, - FAR uint16_t *accum) -{ -#if 0 /* Probably not necessary... untested */ - /* Read-ahead one pixel */ - - *accum = lcd->read(lcd); -#endif -} -#endif - -/************************************************************************************** - * Name: mio283qt2_gramread - * - * Description: - * Read one correctly aligned pixel from the GRAM memory. Possibly shifting the - * data and possibly swapping red and green components. - * - * - ILI932x: Unknown -- assuming colors are in the color order - * - **************************************************************************************/ - -#ifndef CONFIG_LCD_NOGETRUN -static inline uint16_t mio283qt2_gramread(FAR struct mio283qt2_lcd_s *lcd, - FAR uint16_t *accum) -{ - /* Read the value (GRAM register already selected) */ - - return lcd->read(lcd); -} -#endif - -/************************************************************************************** - * Name: mio283qt2_setarea - * - * Description: - * Set the cursor position. In landscape mode, the "column" is actually the physical - * Y position and the "row" is the physical X position. - * - **************************************************************************************/ - -static void mio283qt2_setarea(FAR struct mio283qt2_lcd_s *lcd, - uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) -{ - mio283qt2_putreg(lcd, 0x03, (x0 & 0x00ff)); /* set x0 */ - mio283qt2_putreg(lcd, 0x02, (x0 >> 8)); /* set x0 */ - mio283qt2_putreg(lcd, 0x05, (x1 & 0x00ff)); /* set x1 */ - mio283qt2_putreg(lcd, 0x04, (x1 >> 8)); /* set x1 */ - mio283qt2_putreg(lcd, 0x07, (y0 & 0x00ff)); /* set y0 */ - mio283qt2_putreg(lcd, 0x06, (y0 >> 8)); /* set y0 */ - mio283qt2_putreg(lcd, 0x09, (y1 & 0x00ff)); /* set y1 */ - mio283qt2_putreg(lcd, 0x08, (y1 >> 8)); /* set y1 */ -} - -/************************************************************************************** - * Name: mio283qt2_dumprun - * - * Description: - * Dump the contexts of the run buffer: - * - * run - The buffer in containing the run read to be dumped - * npixels - The number of pixels to dump - * - **************************************************************************************/ - -#if 0 /* Sometimes useful */ -static void mio283qt2_dumprun(FAR const char *msg, FAR uint16_t *run, size_t npixels) -{ - int i, j; - - syslog("\n%s:\n", msg); - for (i = 0; i < npixels; i += 16) - { - up_putc(' '); - syslog(" "); - for (j = 0; j < 16; j++) - { - syslog(" %04x", *run++); - } - up_putc('\n'); - } -} -#endif - -/************************************************************************************** - * Name: mio283qt2_putrun - * - * Description: - * This method can be used to write a partial raster line to the LCD: - * - * row - Starting row to write to (range: 0 <= row < yres) - * col - Starting column to write to (range: 0 <= col <= xres-npixels) - * buffer - The buffer containing the run to be written to the LCD - * npixels - The number of pixels to write to the LCD - * (range: 0 < npixels <= xres-col) - * - **************************************************************************************/ - -static int mio283qt2_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer, - size_t npixels) -{ - FAR struct mio283qt2_dev_s *priv = &g_lcddev; - FAR struct mio283qt2_lcd_s *lcd = priv->lcd; - FAR const uint16_t *src = (FAR const uint16_t*)buffer; - int i; - - /* Buffer must be provided and aligned to a 16-bit address boundary */ - - lcdvdbg("row: %d col: %d npixels: %d\n", row, col, npixels); - DEBUGASSERT(buffer && ((uintptr_t)buffer & 1) == 0); - - /* Select the LCD */ - - lcd->select(lcd); - - /* Write the run to GRAM. */ - - mio283qt2_setarea(lcd, col, row, col + npixels - 1, row); - mio283qt2_gramselect(lcd); - - for (i = 0; i < npixels; i++) - { - mio283qt2_gramwrite(lcd, *src); - src++; - } - - /* De-select the LCD */ - - lcd->deselect(lcd); - return OK; -} - -/************************************************************************************** - * Name: mio283qt2_getrun - * - * Description: - * This method can be used to read a partial raster line from the LCD: - * - * 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) - * - **************************************************************************************/ - -static int mio283qt2_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer, - size_t npixels) -{ -#ifndef CONFIG_LCD_NOGETRUN - FAR struct mio283qt2_dev_s *priv = &g_lcddev; - FAR struct mio283qt2_lcd_s *lcd = priv->lcd; - FAR uint16_t *dest = (FAR uint16_t*)buffer; - uint16_t accum; - int i; - - /* Buffer must be provided and aligned to a 16-bit address boundary */ - - lcdvdbg("row: %d col: %d npixels: %d\n", row, col, npixels); - DEBUGASSERT(buffer && ((uintptr_t)buffer & 1) == 0); - - /* Select the LCD */ - - lcd->select(lcd); - - /* Read the run from GRAM. */ - - /* Select the LCD */ - - lcd->select(lcd); - - /* Red the run fram GRAM. */ - - mio283qt2_setarea(lcd, col, row, col + npixels - 1, row); - mio283qt2_gramselect(lcd); - - /* Prime the pump for unaligned read data */ - - mio283qt2_readsetup(lcd, &accum); - - for (i = 0; i < npixels; i++) - { - *dest++ = mio283qt2_gramread(lcd, &accum); - } - - /* De-select the LCD */ - - lcd->deselect(lcd); - return OK; -#else - return -ENOSYS; -#endif -} - -/************************************************************************************** - * Name: mio283qt2_getvideoinfo - * - * Description: - * Get information about the LCD video controller configuration. - * - **************************************************************************************/ - -static int mio283qt2_getvideoinfo(FAR struct lcd_dev_s *dev, - FAR struct fb_videoinfo_s *vinfo) -{ - DEBUGASSERT(dev && vinfo); - lcdvdbg("fmt: %d xres: %d yres: %d nplanes: 1\n", - MIO283QT2_COLORFMT, MIO283QT2_XRES, MIO283QT2_XRES); - - vinfo->fmt = MIO283QT2_COLORFMT; /* Color format: RGB16-565: RRRR RGGG GGGB BBBB */ - vinfo->xres = MIO283QT2_XRES; /* Horizontal resolution in pixel columns */ - vinfo->yres = MIO283QT2_YRES; /* Vertical resolution in pixel rows */ - vinfo->nplanes = 1; /* Number of color planes supported */ - return OK; -} - -/************************************************************************************** - * Name: mio283qt2_getplaneinfo - * - * Description: - * Get information about the configuration of each LCD color plane. - * - **************************************************************************************/ - -static int mio283qt2_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planeno, - FAR struct lcd_planeinfo_s *pinfo) -{ - FAR struct mio283qt2_dev_s *priv = (FAR struct mio283qt2_dev_s *)dev; - - DEBUGASSERT(dev && pinfo && planeno == 0); - lcdvdbg("planeno: %d bpp: %d\n", planeno, MIO283QT2_BPP); - - pinfo->putrun = mio283qt2_putrun; /* Put a run into LCD memory */ - pinfo->getrun = mio283qt2_getrun; /* Get a run from LCD memory */ - pinfo->buffer = (uint8_t*)priv->runbuffer; /* Run scratch buffer */ - pinfo->bpp = MIO283QT2_BPP; /* Bits-per-pixel */ - return OK; -} - -/************************************************************************************** - * Name: mio283qt2_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. - * - **************************************************************************************/ - -static int mio283qt2_getpower(FAR struct lcd_dev_s *dev) -{ - lcdvdbg("power: %d\n", 0); - return g_lcddev.power; -} - -/************************************************************************************** - * Name: mio283qt2_poweroff - * - * Description: - * Enable/disable LCD panel power (0: full off - CONFIG_LCD_MAXPOWER: full on). On - * backlit LCDs, this setting may correspond to the backlight setting. - * - **************************************************************************************/ - -static int mio283qt2_poweroff(FAR struct mio283qt2_lcd_s *lcd) -{ - /* Set the backlight off */ - - lcd->backlight(lcd, 0); - - /* Turn the display off */ - - mio283qt2_putreg(lcd, 0x28, 0x0000); /* GON=0, DTE=0, D=0 */ - - /* Remember the power off state */ - - g_lcddev.power = 0; - return OK; -} - -/************************************************************************************** - * Name: mio283qt2_setpower - * - * Description: - * Enable/disable LCD panel power (0: full off - CONFIG_LCD_MAXPOWER: full on). On - * backlit LCDs, this setting may correspond to the backlight setting. - * - **************************************************************************************/ - -static int mio283qt2_setpower(FAR struct lcd_dev_s *dev, int power) -{ - FAR struct mio283qt2_dev_s *priv = (FAR struct mio283qt2_dev_s *)dev; - FAR struct mio283qt2_lcd_s *lcd = priv->lcd; - - lcdvdbg("power: %d\n", power); - DEBUGASSERT((unsigned)power <= CONFIG_LCD_MAXPOWER); - - /* Set new power level */ - - if (power > 0) - { - /* Set the backlight level */ - - lcd->backlight(lcd, power); - - /* Then turn the display on: - * D=ON(3) CM=0 DTE=1 GON=1 SPT=0 VLE=0 PT=0 - */ - - /* Display on */ - - mio283qt2_putreg(lcd, 0x28, 0x0038); /* GON=1, DTE=1, D=2 */ - up_mdelay(40); - mio283qt2_putreg(lcd, 0x28, 0x003c); /* GON=1, DTE=1, D=3 */ - - g_lcddev.power = power; - } - else - { - /* Turn the display off */ - - mio283qt2_poweroff(lcd); - } - - return OK; -} - -/************************************************************************************** - * Name: mio283qt2_getcontrast - * - * Description: - * Get the current contrast setting (0-CONFIG_LCD_MAXCONTRAST). - * - **************************************************************************************/ - -static int mio283qt2_getcontrast(FAR struct lcd_dev_s *dev) -{ - lcdvdbg("Not implemented\n"); - return -ENOSYS; -} - -/************************************************************************************** - * Name: mio283qt2_setcontrast - * - * Description: - * Set LCD panel contrast (0-CONFIG_LCD_MAXCONTRAST). - * - **************************************************************************************/ - -static int mio283qt2_setcontrast(FAR struct lcd_dev_s *dev, unsigned int contrast) -{ - lcdvdbg("contrast: %d\n", contrast); - return -ENOSYS; -} - -/************************************************************************************** - * Name: mio283qt2_hwinitialize - * - * Description: - * Initialize the LCD hardware. - * - **************************************************************************************/ - -static inline int mio283qt2_hwinitialize(FAR struct mio283qt2_dev_s *priv) -{ - FAR struct mio283qt2_lcd_s *lcd = priv->lcd; -#ifndef CONFIG_LCD_NOGETRUN - uint16_t id; -#endif - - /* Select the LCD */ - - lcd->select(lcd); - - /* Read the HIMAX ID registger (0x00) */ - -#ifndef CONFIG_LCD_NOGETRUN - id = mio283qt2_readreg(lcd, 0x00); - lcddbg("LCD ID: %04x\n", id); - - /* Check if the ID is for the MIO283QT2 */ - - if (id == HIMAX_ID) -#endif - { - /* Driving ability */ - - mio283qt2_putreg(lcd, 0xea, 0x0000); /* PTBA[15:8] */ - mio283qt2_putreg(lcd, 0xeb, 0x0020); /* PTBA[7:0] */ - mio283qt2_putreg(lcd, 0xec, 0x000c); /* STBA[15:8] */ - mio283qt2_putreg(lcd, 0xed, 0x00c4); /* STBA[7:0] */ - mio283qt2_putreg(lcd, 0xe8, 0x0040); /* OPON[7:0] */ - mio283qt2_putreg(lcd, 0xe9, 0x0038); /* OPON1[7:0] */ - mio283qt2_putreg(lcd, 0xf1, 0x0001); /* OTPS1B */ - mio283qt2_putreg(lcd, 0xf2, 0x0010); /* GEN */ - mio283qt2_putreg(lcd, 0x27, 0x00a3); - - /* Power voltage */ - - mio283qt2_putreg(lcd, 0x1b, 0x001b); /* VRH = 4.65 */ - mio283qt2_putreg(lcd, 0x1a, 0x0001); /* BT */ - mio283qt2_putreg(lcd, 0x24, 0x002f); /* VMH */ - mio283qt2_putreg(lcd, 0x25, 0x0057); /* VML */ - - /* Vcom offset */ - - mio283qt2_putreg(lcd, 0x23, 0x008d); /* For flicker adjust */ - - /* Power on */ - - mio283qt2_putreg(lcd, 0x18, 0x0036); - mio283qt2_putreg(lcd, 0x19, 0x0001); /* Start oscillator */ - mio283qt2_putreg(lcd, 0x01, 0x0000); /* Wakeup */ - mio283qt2_putreg(lcd, 0x1f, 0x0088); - up_mdelay(5); - mio283qt2_putreg(lcd, 0x1f, 0x0080); - up_mdelay(5); - mio283qt2_putreg(lcd, 0x1f, 0x0090); - up_mdelay(5); - mio283qt2_putreg(lcd, 0x1f, 0x00d0); - up_mdelay(5); - - /* Gamma 2.8 setting */ - - mio283qt2_putreg(lcd, 0x40, 0x0000); - mio283qt2_putreg(lcd, 0x41, 0x0000); - mio283qt2_putreg(lcd, 0x42, 0x0001); - mio283qt2_putreg(lcd, 0x43, 0x0013); - mio283qt2_putreg(lcd, 0x44, 0x0010); - mio283qt2_putreg(lcd, 0x45, 0x0026); - mio283qt2_putreg(lcd, 0x46, 0x0008); - mio283qt2_putreg(lcd, 0x47, 0x0051); - mio283qt2_putreg(lcd, 0x48, 0x0002); - mio283qt2_putreg(lcd, 0x49, 0x0012); - mio283qt2_putreg(lcd, 0x4a, 0x0018); - mio283qt2_putreg(lcd, 0x4b, 0x0019); - mio283qt2_putreg(lcd, 0x4c, 0x0014); - - mio283qt2_putreg(lcd, 0x50, 0x0019); - mio283qt2_putreg(lcd, 0x51, 0x002f); - mio283qt2_putreg(lcd, 0x52, 0x002c); - mio283qt2_putreg(lcd, 0x53, 0x003e); - mio283qt2_putreg(lcd, 0x54, 0x003f); - mio283qt2_putreg(lcd, 0x55, 0x003f); - mio283qt2_putreg(lcd, 0x56, 0x002e); - mio283qt2_putreg(lcd, 0x57, 0x0077); - mio283qt2_putreg(lcd, 0x58, 0x000b); - mio283qt2_putreg(lcd, 0x59, 0x0006); - mio283qt2_putreg(lcd, 0x5a, 0x0007); - mio283qt2_putreg(lcd, 0x5b, 0x000d); - mio283qt2_putreg(lcd, 0x5c, 0x001d); - mio283qt2_putreg(lcd, 0x5d, 0x00cc); - - /* 4K Color Selection */ - - mio283qt2_putreg(lcd, 0x17, 0x0003); - mio283qt2_putreg(lcd, 0x17, 0x0005); /* 0x0005=65k, 0x0006=262k */ - - /* Panel characteristics */ - - mio283qt2_putreg(lcd, 0x36, 0x0000); - - /* Display Setting */ - - mio283qt2_putreg(lcd, 0x01, 0x0000); /* IDMON=0, INVON=0, NORON=0, PTLON=0 */ - -#if defined(CONFIG_LCD_LANDSCAPE) - mio283qt2_putreg(lcd, 0x16, 0x00a8); /* MY=1, MX=0, MV=1, ML=0, BGR=1 */ -#elif defined(CONFIG_LCD_PORTRAIT) - mio283qt2_putreg(lcd, 0x16, 0x0008); /* MY=0, MX=0, MV=0, ML=0, BGR=1 */ -#elif defined(CONFIG_LCD_RLANDSCAPE) - mio283qt2_putreg(lcd, 0x16, 0x0068); /* MY=0, MX=1, MV=1, ML=0, BGR=1 */ -#elif defined(CONFIG_LCD_RPORTRAIT) - mio283qt2_putreg(lcd, 0x16, 0x00c8); /* MY=1, MX=0, MV=1, ML=0, BGR=1 */ -#endif - - /* Window setting */ - - mio283qt2_setarea(lcd, 0, 0, (MIO283QT2_XRES-1), (MIO283QT2_YRES-1)); - return OK; - } -#ifndef CONFIG_LCD_NOGETRUN - else - { - lcddbg("Unsupported LCD type\n"); - return -ENODEV; - } -#endif - - /* De-select the LCD */ - - lcd->deselect(lcd); -} - - /************************************************************************************* - * Public Functions - **************************************************************************************/ - -/************************************************************************************** - * Name: mio283qt2_lcdinitialize - * - * Description: - * Initialize the LCD 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). - * - **************************************************************************************/ - -FAR struct lcd_dev_s *mio283qt2_lcdinitialize(FAR struct mio283qt2_lcd_s *lcd) -{ - int ret; - - lcdvdbg("Initializing\n"); - - /* If we ccould support multiple MIO283QT2 devices, this is where we would allocate - * a new driver data structure... but we can't. Why not? Because of a bad should - * the form of the getrun() and putrun methods. - */ - - FAR struct mio283qt2_dev_s *priv = &g_lcddev; - - /* Initialize the driver data structure */ - - priv->dev.getvideoinfo = mio283qt2_getvideoinfo; - priv->dev.getplaneinfo = mio283qt2_getplaneinfo; - priv->dev.getpower = mio283qt2_getpower; - priv->dev.setpower = mio283qt2_setpower; - priv->dev.getcontrast = mio283qt2_getcontrast; - priv->dev.setcontrast = mio283qt2_setcontrast; - priv->lcd = lcd; - - /* Configure and enable LCD */ - - ret = mio283qt2_hwinitialize(priv); - if (ret == OK) - { - /* Clear the display (setting it to the color 0=black) */ - - mio283qt2_clear(&priv->dev, 0); - - /* Turn the display off */ - - mio283qt2_poweroff(lcd); - return &g_lcddev.dev; - } - - return NULL; -} - -/************************************************************************************** - * Name: mio283qt2_clear - * - * Description: - * This is a non-standard LCD interface just for the stm3240g-EVAL board. 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. - * - **************************************************************************************/ - -void mio283qt2_clear(FAR struct lcd_dev_s *dev, uint16_t color) -{ - FAR struct mio283qt2_dev_s *priv = (FAR struct mio283qt2_dev_s *)dev; - FAR struct mio283qt2_lcd_s *lcd = priv->lcd; - uint32_t i; - - /* Select the LCD and set the drawring area */ - - lcd->select(lcd); - mio283qt2_setarea(lcd, 0, 0, (MIO283QT2_XRES-1), (MIO283QT2_YRES-1)); - - /* Prepare to write GRAM data */ - - mio283qt2_gramselect(lcd); - - /* Copy color into all of GRAM. Orientation does not matter in this case. */ - - for (i = 0; i < MIO283QT2_XRES * MIO283QT2_YRES; i++) - { - mio283qt2_gramwrite(lcd, color); - } - - /* De-select the LCD */ - - lcd->deselect(lcd); -} - -#endif /* CONFIG_LCD_MIO283QT2 */ diff --git a/nuttx/drivers/lcd/nokia6100.c b/nuttx/drivers/lcd/nokia6100.c deleted file mode 100644 index 7354b8a91..000000000 --- a/nuttx/drivers/lcd/nokia6100.c +++ /dev/null @@ -1,1230 +0,0 @@ -/************************************************************************************** - * drivers/lcd/nokia6100.c - * Nokia 6100 LCD Display Driver - * - * Copyright (C) 2010-2011 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt <gnutt@nuttx.org> - * - * References: - * "Nokia 6100 LCD Display Driver," Revision 1, James P. Lynch ("Nokia 6100 LCD - * Display Driver.pdf") - * "S1D15G0D08B000," Seiko Epson Corportation, 2002. - * "Data Sheet, PCF8833 STN RGB 132x132x3 driver," Phillips, 2003 Feb 14. - * - * 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 written 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. - * - **************************************************************************************/ - -/************************************************************************************** - * Included Files - **************************************************************************************/ - -#include <nuttx/config.h> - -#include <sys/types.h> -#include <stdint.h> -#include <stdbool.h> -#include <string.h> -#include <errno.h> -#include <debug.h> - -#include <nuttx/arch.h> -#include <nuttx/spi.h> -#include <nuttx/lcd/lcd.h> -#include <nuttx/lcd/nokia6100.h> - -#ifdef CONFIG_NOKIA6100_PCF8833 -# include "pcf8833.h" -#endif -#ifdef CONFIG_NOKIA6100_S1D15G10 -# include "s1d15g10.h" -#endif - -/************************************************************************************** - * Pre-processor Definitions - **************************************************************************************/ - -/* Configuration **********************************************************************/ -/* Verify that all configuration requirements have been met */ - -/* Nokia 6100 Configuration Settings: - * - * CONFIG_NOKIA6100_SPIMODE - Controls the SPI mode - * CONFIG_NOKIA6100_FREQUENCY - Define to use a different bus frequency - * CONFIG_NOKIA6100_NINTERFACES - Specifies the number of physical Nokia 6100 devices that - * will be supported. - * CONFIG_NOKIA6100_BPP - Device supports 8, 12, and 16 bits per pixel. - * CONFIG_NOKIA6100_S1D15G10 - Selects the Epson S1D15G10 display controller - * CONFIG_NOKIA6100_PCF8833 - Selects the Phillips PCF8833 display controller - * CONFIG_NOKIA6100_BLINIT - Initial backlight setting - * - * The following may need to be tuned for your hardware: - * CONFIG_NOKIA6100_INVERT - Display inversion, 0 or 1, Default: 1 - * CONFIG_NOKIA6100_MY - Display row direction, 0 or 1, Default: 0 - * CONFIG_NOKIA6100_MX - Display column direction, 0 or 1, Default: 1 - * CONFIG_NOKIA6100_V - Display address direction, 0 or 1, Default: 0 - * CONFIG_NOKIA6100_ML - Display scan direction, 0 or 1, Default: 0 - * CONFIG_NOKIA6100_RGBORD - Display RGB order, 0 or 1, Default: 0 - * - * Required LCD driver settings: - * CONFIG_LCD_NOKIA6100 - Enable Nokia 6100 support - * CONFIG_LCD_MAXCONTRAST - must be 63 with the Epson controller and 127 with - * the Phillips controller. - * CONFIG_LCD_MAXPOWER - Maximum value of backlight setting. The backlight control is - * managed outside of the 6100 driver so this value has no meaning to the driver. - */ - -/* Mode 0,0 should be use. However, somtimes you need to tinker with these things. */ - -#ifndef CONFIG_NOKIA6100_SPIMODE -# define CONFIG_NOKIA6100_SPIMODE SPIDEV_MODE0 -#endif - -/* Default frequency: 1Mhz */ - -#ifndef CONFIG_NOKIA6100_FREQUENCY -# define CONFIG_NOKIA6100_FREQUENCY 1000000 -#endif - -/* CONFIG_NOKIA6100_NINTERFACES determines the number of physical interfaces - * that will be supported. - */ - -#ifndef CONFIG_NOKIA6100_NINTERFACES -# define CONFIG_NOKIA6100_NINTERFACES 1 -#endif - -#if CONFIG_NOKIA6100_NINTERFACES != 1 -# error "This implementation supports only a single LCD device" -#endif - -/* Only support for 8 and 12 BPP currently implemented */ - -#if !defined(CONFIG_NOKIA6100_BPP) -# warning "Assuming 8BPP" -# define CONFIG_NOKIA6100_BPP 8 -#endif - -#if CONFIG_NOKIA6100_BPP != 8 && CONFIG_NOKIA6100_BPP != 12 -# if CONFIG_NOKIA6100_BPP == 16 -# error "Support for 16BPP no yet implemented" -# else -# error "LCD supports only 8, 12, and 16BPP" -# endif -#endif - -#if CONFIG_NOKIA6100_BPP == 8 -# ifdef CONFIG_NX_DISABLE_8BPP -# warning "8-bit pixel support needed" -# endif -#elif CONFIG_NOKIA6100_BPP == 12 -# if defined(CONFIG_NX_DISABLE_12BPP) || !defined(CONFIG_NX_PACKEDMSFIRST) -# warning "12-bit, big-endian pixel support needed" -# endif -#elif CONFIG_NOKIA6100_BPP == 16 -# ifdef CONFIG_NX_DISABLE_16BPP -# warning "16-bit pixel support needed" -# endif -#endif - -/* Exactly one LCD controller must be selected. "The Olimex boards have both display - * controllers possible; if the LCD has a GE-12 sticker on it, it’s a Philips PCF8833. - * If it has a GE-8 sticker, it’s an Epson controller." - */ - -#if defined(CONFIG_NOKIA6100_S1D15G10) && defined(CONFIG_NOKIA6100_PCF8833) -# error "Both CONFIG_NOKIA6100_S1D15G10 and CONFIG_NOKIA6100_PCF8833 are defined" -#endif - -#if !defined(CONFIG_NOKIA6100_S1D15G10) && !defined(CONFIG_NOKIA6100_PCF8833) -# error "One of CONFIG_NOKIA6100_S1D15G10 or CONFIG_NOKIA6100_PCF8833 must be defined" -#endif - -/* Delay geometry defaults */ - -#ifndef CONFIG_NOKIA6100_INVERT -# define CONFIG_NOKIA6100_INVERT 1 -#endif - -#ifndef CONFIG_NOKIA6100_MY -# define CONFIG_NOKIA6100_MY 0 -#endif - -#ifndef CONFIG_NOKIA6100_MX -# define CONFIG_NOKIA6100_MX 1 -#endif - -#ifndef CONFIG_NOKIA6100_V -# define CONFIG_NOKIA6100_V 0 -#endif - -#ifndef CONFIG_NOKIA6100_ML -# define CONFIG_NOKIA6100_ML 0 -#endif - -#ifndef CONFIG_NOKIA6100_RGBORD -# define CONFIG_NOKIA6100_RGBORD 0 -#endif - -/* Check contrast selection */ - -#ifdef CONFIG_NOKIA6100_S1D15G10 - -# if !defined(CONFIG_LCD_MAXCONTRAST) -# define CONFIG_LCD_MAXCONTRAST 63 -# endif -# if CONFIG_LCD_MAXCONTRAST != 63 -# error "CONFIG_LCD_MAXCONTRAST must be 63 with the Epson LCD controller" -# endif -# define NOKIA_DEFAULT_CONTRAST 32 - -#else /* CONFIG_NOKIA6100_PCF8833 */ - -# if !defined(CONFIG_LCD_MAXCONTRAST) -# define CONFIG_LCD_MAXCONTRAST 127 -# endif -# if CONFIG_LCD_MAXCONTRAST != 127 -# error "CONFIG_LCD_MAXCONTRAST must be 127 with the Phillips LCD controller" -# endif -# define NOKIA_DEFAULT_CONTRAST 48 - -#endif - -/* Check initial backlight setting */ - -#ifndef CONFIG_NOKIA6100_BLINIT -# define CONFIG_NOKIA6100_BLINIT (NOKIA_DEFAULT_CONTRAST/3) -#endif - -/* Word width must be 9 bits */ - -#if defined(CONFIG_NOKIA6100_WORDWIDTH) && CONFIG_NOKIA6100_WORDWIDTH != 9 -# error "CONFIG_NOKIA6100_WORDWIDTH must be 9" -#endif -#ifndef CONFIG_NOKIA6100_WORDWIDTH -# define CONFIG_NOKIA6100_WORDWIDTH 9 -#endif - -/* If bit 9 is set, the byte is data; clear for commands */ - -#define NOKIA_LCD_DATA (1 << 8) - -/* Define CONFIG_LCD_REGDEBUG to enable register-level debug output. - * (Verbose debug must also be enabled) - */ - -#ifndef CONFIG_DEBUG -# undef CONFIG_DEBUG_VERBOSE -# undef CONFIG_DEBUG_GRAPHICS -#endif - -#ifndef CONFIG_DEBUG_VERBOSE -# undef CONFIG_LCD_REGDEBUG -#endif - -/* Controller independent definitions *************************************************/ - -#ifdef CONFIG_NOKIA6100_PCF8833 -# define LCD_NOP PCF8833_NOP -# define LCD_RAMWR PCF8833_RAMWR -# define LCD_PASET PCF8833_PASET -# define LCD_CASET PCF8833_CASET -#endif -#ifdef CONFIG_NOKIA6100_S1D15G10 -# define LCD_NOP S1D15G10_NOP -# define LCD_RAMWR S1D15G10_RAMWR -# define LCD_PASET S1D15G10_PASET -# define LCD_CASET S1D15G10_CASET -#endif - -/* Color Properties *******************************************************************/ - -/* Display Resolution */ - -#define NOKIA_XRES 132 -#define NOKIA_YRES 132 - -/* Color depth and format */ - -#if CONFIG_NOKIA6100_BPP == 8 -# define NOKIA_BPP 8 -# define NOKIA_COLORFMT FB_FMT_RGB8_332 -# define NOKIA_STRIDE NOKIA_XRES -# define NOKIA_PIX2BYTES(p) (p) -#elif CONFIG_NOKIA6100_BPP == 12 -# define NOKIA_BPP 12 -# define NOKIA_COLORFMT FB_FMT_RGB12_444 -# define NOKIA_STRIDE ((3*NOKIA_XRES+1)/2) -# define NOKIA_PIX2BYTES(p) ((3*(p)+1)/2) -#elif CONFIG_NOKIA6100_BPP == 16 -# define NOKIA_BPP 16 -# define NOKIA_COLORFMT FB_FMT_RGB16_565 -# define NOKIA_STRIDE (2*NOKIA_XRES) -# define NOKIA_PIX2BYTES(p) (2*(p)) -#endif - -/* Handle any potential strange behavior at edges */ - -#if 0 /* REVISIT */ -#define NOKIA_PGBIAS 2 /* May not be necessary */ -#define NOKIA_COLBIAS 0 -#define NOKIA_XBIAS 2 /* May not be necessary, if so need to subtract from XRES */ -#define NOKIA_YBIAS 0 -#else -#define NOKIA_PGBIAS 0 -#define NOKIA_COLBIAS 0 -#define NOKIA_XBIAS 0 -#define NOKIA_YBIAS 0 -#endif - -#define NOKIA_ENDPAGE 131 -#define NOKIA_ENDCOL 131 - -/* Debug ******************************************************************************/ - -#ifdef CONFIG_LCD_REGDEBUG -# define lcddbg(format, arg...) llvdbg(format, ##arg) -#else -# define lcddbg(x...) -#endif - -/************************************************************************************** - * Private Type Definition - **************************************************************************************/ - -/* This structure describes the state of this driver */ - -struct nokia_dev_s -{ - /* Publically visible device structure */ - - struct lcd_dev_s dev; - - /* Private LCD-specific information follows */ - - FAR struct spi_dev_s *spi; /* Contained SPI driver instance */ - uint8_t contrast; /* Current contrast setting */ - uint8_t power; /* Current power (backlight) setting */ -}; - -/************************************************************************************** - * Private Function Protototypes - **************************************************************************************/ - -/* SPI support */ - -static inline void nokia_configspi(FAR struct spi_dev_s *spi); -#ifdef CONFIG_SPI_OWNBUS -static inline void nokia_select(FAR struct spi_dev_s *spi); -static inline void nokia_deselect(FAR struct spi_dev_s *spi); -#else -static void nokia_select(FAR struct spi_dev_s *spi); -static void nokia_deselect(FAR struct spi_dev_s *spi); -#endif -static void nokia_sndcmd(FAR struct spi_dev_s *spi, const uint8_t cmd); -static void nokia_cmdarray(FAR struct spi_dev_s *spi, int len, const uint8_t *cmddata); -static void nokia_clrram(FAR struct spi_dev_s *spi); - -/* LCD Data Transfer Methods */ - -static int nokia_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer, - size_t npixels); -static int nokia_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer, - size_t npixels); - -/* LCD Configuration */ - -static int nokia_getvideoinfo(FAR struct lcd_dev_s *dev, - FAR struct fb_videoinfo_s *vinfo); -static int nokia_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planeno, - FAR struct lcd_planeinfo_s *pinfo); - -/* LCD RGB Mapping */ - -#ifdef CONFIG_FB_CMAP -# error "RGB color mapping not supported by this driver" -#endif - -/* Cursor Controls */ - -#ifdef CONFIG_FB_HWCURSOR -# error "Cursor control not supported by this driver" -#endif - -/* LCD Specific Controls */ - -static int nokia_getpower(struct lcd_dev_s *dev); -static int nokia_setpower(struct lcd_dev_s *dev, int power); -static int nokia_getcontrast(struct lcd_dev_s *dev); -static int nokia_setcontrast(struct lcd_dev_s *dev, unsigned int contrast); - -/* Initialization */ - -static int nokia_initialize(struct nokia_dev_s *priv); - -/************************************************************************************** - * Private Data - **************************************************************************************/ - -/* This is working memory allocated by the LCD driver for each LCD device - * and for each color plane. This memory will hold one raster line of data. - * The size of the allocated run buffer must therefore be at least - * (bpp * xres / 8). Actual alignment of the buffer must conform to the - * bitwidth of the underlying pixel type. - * - * If there are multiple planes, they may share the same working buffer - * because different planes will not be operate on concurrently. However, - * if there are multiple LCD devices, they must each have unique run buffers. - */ - -#if CONFIG_NOKIA6100_BPP == 8 -static uint8_t g_runbuffer[NOKIA_XRES]; -#elif CONFIG_NOKIA6100_BPP == 12 -static uint8_t g_runbuffer[(3*NOKIA_XRES+1)/2]; -#else /* CONFIG_NOKIA6100_BPP == 16 */ -static uint16_t g_runbuffer[NOKIA_XRES]; -#endif - -/* g_rowbuf is another buffer, but used internally by the Nokia 6100 driver in order - * expand the pixel data into 9-bit data needed by the LCD. There are some - * customizations that would eliminate the need for this extra buffer and for the - * extra expansion/copy, but those customizations would require a special, non-standard - * SPI driver that could expand 8- to 9-bit data on the fly. - */ - -static uint16_t g_rowbuf[NOKIA_STRIDE+1]; - -/* Device Driver Data Structures ******************************************************/ - -/* This structure describes the overall LCD video controller */ - -static const struct fb_videoinfo_s g_videoinfo = -{ - .fmt = NOKIA_COLORFMT, /* Color format: RGB16-565: RRRR RGGG GGGB BBBB */ - .xres = NOKIA_XRES, /* Horizontal resolution in pixel columns */ - .yres = NOKIA_YRES, /* Vertical resolution in pixel rows */ - .nplanes = 1, /* Number of color planes supported */ -}; - -/* This is the standard, NuttX Plane information object */ - -static const struct lcd_planeinfo_s g_planeinfo = -{ - .putrun = nokia_putrun, /* Put a run into LCD memory */ - .getrun = nokia_getrun, /* Get a run from LCD memory */ - .buffer = (uint8_t*)g_runbuffer, /* Run scratch buffer */ - .bpp = NOKIA_BPP, /* Bits-per-pixel */ -}; - -/* This is the standard, NuttX LCD driver object */ - -static struct nokia_dev_s g_lcddev = -{ - .dev = - { - /* LCD Configuration */ - - .getvideoinfo = nokia_getvideoinfo, - .getplaneinfo = nokia_getplaneinfo, - - /* LCD RGB Mapping -- Not supported */ - /* Cursor Controls -- Not supported */ - - /* LCD Specific Controls */ - - .getpower = nokia_getpower, - .setpower = nokia_setpower, - .getcontrast = nokia_getcontrast, - .setcontrast = nokia_setcontrast, - }, -}; - -/* LCD Command Strings ****************************************************************/ - -#ifdef CONFIG_NOKIA6100_S1D15G10 -/* Display control: - * P1: Specifies the CL dividing ratio, F1 and F2 drive-pattern switching period. - * P2: Specifies the duty of the module on block basis - * P3: Specify number of lines to be inversely highlighted on LCD panel - * P4: 0: Dispersion P40= 1: Non-dispersion - */ - -#if 1 // CONFIG_NOKIA6100_BPP == 12 -static const uint8_t g_disctl[] = -{ - S1D15G10_DISCTL, /* Display control */ - DISCTL_CLDIV_2|DISCTL_PERIOD_8, /* P1: Divide clock by 2; switching period = 8 */ -//DISCTL_CLDIV_NONE|DISCTL_PERIOD_8, /* P1: No clock division; switching period = 8 */ - 32, /* P2: nlines/4 - 1 = 132/4 - 1 = 32 */ - 0, /* P3: No inversely highlighted lines */ - 0 /* P4: No disperion */ -}; -#else /* CONFIG_NOKIA6100_BPP == 8 */ -static const uint8_t g_disctl[] = -{ - S1D15G10_DISCTL, /* Display control */ - DISCTL_CLDIV_2|DISCTL_PERIOD_FLD, /* P1: Divide clock by 2; switching period = field */ - 32, /* P2: nlines/4 - 1 = 132/4 - 1 = 32 */ - 0, /* P3: No inversely highlighted lines */ - 0 /* P4: No disperion */ -}; -#endif - -/* Common scan direction: - * P1: Cpecify the common output scan direction. - */ - -static const uint8_t g_comscn[] = -{ - S1D15G10_COMSCN, /* Common scan direction */ - 1 /* 0x01 = Scan 1->68, 132<-69 */ -}; - -/* Power control: - * P1: Turn on or off the liquid crystal driving power circuit, booster/step-down - * circuits and voltage follower circuit. - */ - -static const uint8_t g_pwrctr[] = -{ - S1D15G10_PWRCTR, /* Power control */ - PWCTR_REFVOLTAGE|PWCTR_REGULATOR|PWCTR_BOOSTER2|PWCTR_BOOSTER1 -}; - -/* Data control: - * P1: Specify the normal or inverse display of the page address and also to specify - * the page address scanning direction - * P2: RGB sequence - * P3: Grayscale setup - */ - -static const uint8_t g_datctl[] = -{ - S1D15G10_DATCTL, /* Data control */ - 0 -#if CONFIG_NOKIA6100_MY != 0 /* Display row direction */ - |DATCTL_PGADDR_INV /* Page address inverted */ -#endif -#if CONFIG_NOKIA6100_MX != 0 /* Display column direction */ - |DATCTL_COLADDR_REV /* Column address reversed */ -#endif -#if CONFIG_NOKIA6100_V != 0 /* Display address direction */ - |DATCTL_ADDR_PGDIR /* Address scan in page direction */ -#endif - , -#if CONFIG_NOKIA6100_RGBORD != 0 - DATCTL_BGR, /* RGB->BGR */ -#else - 0, /* RGB->RGB */ -#endif -#if CONFIG_NOKIA6100_BPP == 8 - DATCTL_8GRAY /* Selects 8-bit color */ -#elif CONFIG_NOKIA6100_BPP == 12 - DATCTL_16GRAY_A /* Selects 16-bit color, Type A */ -#else -# error "16-bit mode not yet implemented" -#endif -}; - -/* Voltage control (contrast setting): - * P1: Volume value - * P2: Resistance ratio - * (May need to be tuned for individual displays) - */ - -static const uint8_t g_volctr[] = -{ - S1D15G10_VOLCTR, /* Volume control */ - NOKIA_DEFAULT_CONTRAST, /* Volume value */ - 2 /* Resistance ratio */ -}; - -/* 256-color position set (RGBSET8) */ - -#if CONFIG_NOKIA6100_BPP == 8 -static const uint8_t g_rgbset8[] = -{ - S1D15G10_RGBSET8, /* 256-color position set */ - 0, 2, 4, 6, 9, 11, 13, 15, /* Red tones */ - 0, 2, 4, 6, 9, 11, 13, 15, /* Green tones */ - 0, 5, 10, 15 /* Blue tones */ -}; -#endif - -/* Page address set (PASET) */ - -static const uint8_t g_paset[] = -{ - S1D15G10_PASET, /* Page start address set */ - NOKIA_PGBIAS, - 131 -}; - -/* Column address set (CASET) */ - -static const uint8_t g_caset[] = -{ - S1D15G10_CASET, /* Column start address set */ - NOKIA_COLBIAS, - 131 -}; -#endif /* CONFIG_NOKIA6100_S1D15G10 */ - -#ifdef CONFIG_NOKIA6100_PCF8833 - -/* Color interface pixel format (COLMOD) */ - -#if CONFIG_NOKIA6100_BPP == 12 -static const uint8_t g_colmod[] = -{ - PCF8833_COLMOD, /* Color interface pixel format */ - PCF8833_FMT_12BPS /* 12 bits-per-pixel */ -}; -#else /* CONFIG_NOKIA6100_BPP == 8 */ -static const uint8_t g_colmod[] = -{ - PCF8833_COLMOD, /* Color interface pixel format */ - PCF8833_FMT_8BPS /* 8 bits-per-pixel */ -}; -#endif - -/* Memory data access control(MADCTL) */ - -static const uint8_t g_madctl[] = -{ - PCF8833_MADCTL, /* Memory data access control*/ - 0 -#ifdef CONFIG_NOKIA6100_RGBORD != 0 - |MADCTL_RGB /* RGB->BGR */ -#endif -#ifdef CONFIG_NOKIA6100_MY != 0 /* Display row direction */ - |MADCTL_MY /* Mirror Y */ -#endif -#ifdef CONFIG_NOKIA6100_MX != 0 /* Display column direction */ - |MADCTL_MX /* Mirror X */ -#endif -#ifdef CONFIG_NOKIA6100_V != 0 /* Display address direction */ - |MADCTL_V /* ertical RAM write; in Y direction */ -#endif -#ifdef CONFIG_NOKIA6100_ML != 0 /* Display scan direction */ - |MADCTL_LAO /* Line address order bottom to top */ -#endif -}; - -/* Set contrast (SETCON) */ - -static const uint8_t g_setcon[] = -{ - PCF8833_SETCON, /* Set contrast */ - NOKIA_DEFAULT_CONTRAST -}; - -#endif /* CONFIG_NOKIA6100_PCF8833 */ - -/************************************************************************************** - * Private Functions - **************************************************************************************/ - -/************************************************************************************** - * Function: nokia_configspi - * - * Description: - * Configure the SPI for use with the Nokia 6100 - * - * Parameters: - * spi - Reference to the SPI driver structure - * - * Returned Value: - * None - * - * Assumptions: - * - **************************************************************************************/ - -static inline void nokia_configspi(FAR struct spi_dev_s *spi) -{ - lcddbg("Mode: %d Bits: %d Frequency: %d\n", - CONFIG_NOKIA6100_SPIMODE, CONFIG_NOKIA6100_WORDWIDTH, CONFIG_NOKIA6100_FREQUENCY); - - /* Configure SPI for the Nokia 6100. But only if we own the SPI bus. Otherwise, don't - * bother because it might change. - */ - -#ifdef CONFIG_SPI_OWNBUS - SPI_SETMODE(spi, CONFIG_NOKIA6100_SPIMODE); - SPI_SETBITS(spi, CONFIG_NOKIA6100_WORDWIDTH); - SPI_SETFREQUENCY(spi, CONFIG_NOKIA6100_FREQUENCY) -#endif -} - -/************************************************************************************** - * Function: nokia_select - * - * Description: - * Select the SPI, locking and re-configuring if necessary - * - * Parameters: - * spi - Reference to the SPI driver structure - * - * Returned Value: - * None - * - * Assumptions: - * - **************************************************************************************/ - -#ifdef CONFIG_SPI_OWNBUS -static inline void nokia_select(FAR struct spi_dev_s *spi) -{ - /* We own the SPI bus, so just select the chip */ - - lcddbg("SELECTED\n"); - SPI_SELECT(spi, SPIDEV_DISPLAY, true); -} -#else -static void nokia_select(FAR struct spi_dev_s *spi) -{ - /* Select Nokia 6100 chip (locking the SPI bus in case there are multiple - * devices competing for the SPI bus - */ - - lcddbg("SELECTED\n"); - SPI_LOCK(spi, true); - SPI_SELECT(spi, SPIDEV_DISPLAY, true); - - /* Now make sure that the SPI bus is configured for the Nokia 6100 (it - * might have gotten configured for a different device while unlocked) - */ - - SPI_SETMODE(spi, CONFIG_NOKIA6100_SPIMODE); - SPI_SETBITS(spi, CONFIG_NOKIA6100_WORDWIDTH); - SPI_SETFREQUENCY(spi, CONFIG_NOKIA6100_FREQUENCY); -} -#endif - -/************************************************************************************** - * Function: nokia_deselect - * - * Description: - * De-select the SPI - * - * Parameters: - * spi - Reference to the SPI driver structure - * - * Returned Value: - * None - * - * Assumptions: - * - **************************************************************************************/ - -#ifdef CONFIG_SPI_OWNBUS -static inline void nokia_deselect(FAR struct spi_dev_s *spi) -{ - /* We own the SPI bus, so just de-select the chip */ - - lcddbg("DE-SELECTED\n"); - SPI_SELECT(spi, SPIDEV_DISPLAY, false); -} -#else -static void nokia_deselect(FAR struct spi_dev_s *spi) -{ - /* De-select Nokia 6100 chip and relinquish the SPI bus. */ - - lcddbg("DE-SELECTED\n"); - SPI_SELECT(spi, SPIDEV_DISPLAY, false); - SPI_LOCK(spi, false); -} -#endif - -/************************************************************************************** - * Name: nokia_sndcmd - * - * Description: - * Send a 1-byte command. - * - **************************************************************************************/ - -static void nokia_sndcmd(FAR struct spi_dev_s *spi, const uint8_t cmd) -{ - /* Select the LCD */ - - lcddbg("cmd: %02x\n", cmd); - nokia_select(spi); - - /* Send the command. Bit 8 == 0 denotes a command */ - - (void)SPI_SEND(spi, (uint16_t)cmd); - - /* De-select the LCD */ - - nokia_deselect(spi); -} - -/************************************************************************************** - * Name: nokia_cmddata - * - * Description: - * Send a 1-byte command followed by datlen data bytes. - * - **************************************************************************************/ - -static void nokia_cmddata(FAR struct spi_dev_s *spi, uint8_t cmd, int datlen, - const uint8_t *data) -{ - uint16_t *rowbuf = g_rowbuf; - int i; - - lcddbg("cmd: %02x datlen: %d\n", cmd, datlen); - DEBUGASSERT(datlen <= NOKIA_STRIDE); - - /* Copy the command into the line buffer. Bit 8 == 0 denotes a command. */ - - *rowbuf++ = cmd; - - /* Copy any data after the command into the line buffer */ - - for (i = 0; i < datlen; i++) - { - /* Bit 8 == 1 denotes data */ - - *rowbuf++ = (uint16_t)*data++ | NOKIA_LCD_DATA; - } - - /* Select the LCD */ - - nokia_select(spi); - - /* Send the line buffer. */ - - (void)SPI_SNDBLOCK(spi, g_rowbuf, datlen+1); - - /* De-select the LCD */ - - nokia_deselect(spi); -} - -/************************************************************************************** - * Name: nokia_ramwr - * - * Description: - * Send a RAMWR command followed by datlen data bytes. - * - **************************************************************************************/ - -static void nokia_ramwr(FAR struct spi_dev_s *spi, int datlen, const uint8_t *data) -{ - nokia_cmddata(spi, LCD_RAMWR, datlen, data); -} - -/************************************************************************************** - * Name: nokia_cmdarray - * - * Description: - * Send a RAMWR command followed by len-1 data bytes. - * - **************************************************************************************/ - -static void nokia_cmdarray(FAR struct spi_dev_s *spi, int len, const uint8_t *cmddata) -{ -#ifdef CONFIG_LCD_REGDEBUG - int i; - - for (i = 0; i < len; i++) - { - lcddbg("cmddata[%d]: %02x\n", i, cmddata[i]); - } -#endif - nokia_cmddata(spi, cmddata[0], len-1, &cmddata[1]); -} - -/************************************************************************************** - * Name: nokia_clrram - * - * Description: - * Send a 1-byte command followed by len-1 data bytes. - * - **************************************************************************************/ - -static void nokia_clrram(FAR struct spi_dev_s *spi) -{ - uint16_t *rowbuf = g_rowbuf; - int i; - - /* Set all zero data in the line buffer */ - - for (i = 0; i < NOKIA_STRIDE; i++) - { - /* Bit 8 == 1 denotes data */ - - *rowbuf++ = NOKIA_LCD_DATA; - } - - /* Select the LCD and send the RAMWR command */ - - nokia_select(spi); - SPI_SEND(spi, LCD_RAMWR); - - /* Send the line buffer, once for each row. */ - - for (i = 0; i < NOKIA_YRES; i++) - { - (void)SPI_SNDBLOCK(spi, g_rowbuf, NOKIA_STRIDE); - } - - /* De-select the LCD */ - - nokia_deselect(spi); -} - -/************************************************************************************** - * Name: nokia_putrun - * - * Description: - * This method can be used to write a partial raster line to the LCD: - * - * row - Starting row to write to (range: 0 <= row < yres) - * col - Starting column to write to (range: 0 <= col <= xres-npixels) - * buffer - The buffer containing the run to be written to the LCD - * npixels - The number of pixels to write to the LCD - * (range: 0 < npixels <= xres-col) - * - **************************************************************************************/ - -static int nokia_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer, - size_t npixels) -{ - struct nokia_dev_s *priv = &g_lcddev; - FAR struct spi_dev_s *spi = priv->spi; - uint16_t cmd[3]; - - gvdbg("row: %d col: %d npixels: %d\n", row, col, npixels); - -#if NOKIA_XBIAS > 0 - col += NOKIA_XBIAS; -#endif -#if NOKIA_YBIAS > 0 - row += NOKIA_YBIAS; -#endif - DEBUGASSERT(buffer && col >=0 && (col + npixels) <= NOKIA_XRES && row >= 0 && row < NOKIA_YRES); - - /* Set up to write the run. */ - - nokia_select(spi); - cmd[0] = LCD_PASET; - cmd[1] = col | NOKIA_LCD_DATA; - cmd[2] = NOKIA_ENDPAGE | NOKIA_LCD_DATA; - (void)SPI_SNDBLOCK(spi, cmd, 3); - nokia_deselect(spi); - - /* De-select the LCD */ - - nokia_select(spi); - cmd[0] = LCD_CASET; - cmd[1] = row | NOKIA_LCD_DATA; - cmd[2] = NOKIA_ENDCOL | NOKIA_LCD_DATA; - (void)SPI_SNDBLOCK(spi, cmd, 3); - nokia_deselect(spi); - - /* Then send the run */ - - nokia_ramwr(spi, NOKIA_PIX2BYTES(npixels), buffer); - return OK; -} - -/************************************************************************************** - * Name: nokia_getrun - * - * Description: - * This method can be used to read a partial raster line from the LCD: - * - * 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) - * - **************************************************************************************/ - -static int nokia_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer, - size_t npixels) -{ - gvdbg("row: %d col: %d npixels: %d\n", row, col, npixels); - DEBUGASSERT(buffer && ((uintptr_t)buffer & 1) == 0); - - /* At present, this is a write-only LCD driver */ - -#warning "Not implemented" - return -ENOSYS; -} - -/************************************************************************************** - * Name: nokia_getvideoinfo - * - * Description: - * Get information about the LCD video controller configuration. - * - **************************************************************************************/ - -static int nokia_getvideoinfo(FAR struct lcd_dev_s *dev, - FAR struct fb_videoinfo_s *vinfo) -{ - DEBUGASSERT(dev && vinfo); - gvdbg("fmt: %d xres: %d yres: %d nplanes: %d\n", - g_videoinfo.fmt, g_videoinfo.xres, g_videoinfo.yres, g_videoinfo.nplanes); - memcpy(vinfo, &g_videoinfo, sizeof(struct fb_videoinfo_s)); - return OK; -} - -/************************************************************************************** - * Name: nokia_getplaneinfo - * - * Description: - * Get information about the configuration of each LCD color plane. - * - **************************************************************************************/ - -static int nokia_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planeno, - FAR struct lcd_planeinfo_s *pinfo) -{ - DEBUGASSERT(dev && pinfo && planeno == 0); - gvdbg("planeno: %d bpp: %d\n", planeno, g_planeinfo.bpp); - memcpy(pinfo, &g_planeinfo, sizeof(struct lcd_planeinfo_s)); - return OK; -} - -/************************************************************************************** - * Name: nokia_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. - * - **************************************************************************************/ - -static int nokia_getpower(struct lcd_dev_s *dev) -{ - struct nokia_dev_s *priv = (struct nokia_dev_s *)dev; - gvdbg("power: %d\n", priv->power); - return priv->power; -} - -/************************************************************************************** - * Name: nokia_setpower - * - * Description: - * Enable/disable LCD panel power (0: full off - CONFIG_LCD_MAXPOWER: full on). On - * backlit LCDs, this setting may correspond to the backlight setting. - * - **************************************************************************************/ - -static int nokia_setpower(struct lcd_dev_s *dev, int power) -{ - struct nokia_dev_s *priv = (struct nokia_dev_s *)dev; - int ret; - - gvdbg("power: %d\n", power); - DEBUGASSERT(power <= CONFIG_LCD_MAXPOWER); - - /* Set new power level. The backlight power is controlled outside of the LCD - * assembly and must be managmed by board-specific logic. - */ - - ret = nokia_backlight(power); - if (ret == OK) - { - priv->power = power; - } - return ret; -} - -/************************************************************************************** - * Name: nokia_getcontrast - * - * Description: - * Get the current contrast setting (0-CONFIG_LCD_MAXCONTRAST). - * - **************************************************************************************/ - -static int nokia_getcontrast(struct lcd_dev_s *dev) -{ - struct nokia_dev_s *priv = (struct nokia_dev_s *)dev; - gvdbg("contrast: %d\n", priv->contrast); - return priv->contrast; -} - -/************************************************************************************** - * Name: nokia_setcontrast - * - * Description: - * Set LCD panel contrast (0-CONFIG_LCD_MAXCONTRAST). - * - **************************************************************************************/ - -static int nokia_setcontrast(struct lcd_dev_s *dev, unsigned int contrast) -{ - struct nokia_dev_s *priv = (struct nokia_dev_s *)dev; - - if (contrast < CONFIG_LCD_MAXCONTRAST) - { -#ifdef CONFIG_NOKIA6100_S1D15G10 - while (priv->contrast < contrast) - { - nokia_sndcmd(priv->spi, S1D15G10_VOLUP); - priv->contrast++; - } - while (priv->contrast > contrast) - { - nokia_sndcmd(priv->spi, S1D15G10_VOLDOWN); - priv->contrast--; - } -#else /* CONFIG_NOKIA6100_PCF8833 */ - uint8_t cmd[2]; - - cmd[0] = PCF8833_SETCON; - cmd[1] = priv->contrast; - nokia_sndarry(priv->spi, 2, cmd); - priv->contrast = contrast; -#endif - } - - gvdbg("contrast: %d\n", contrast); - return -ENOSYS; -} - -/************************************************************************************** - * Name: nokia_initialize - * - * Description: - * Initialize the LCD controller. - * - **************************************************************************************/ - -#ifdef CONFIG_NOKIA6100_S1D15G10 -static int nokia_initialize(struct nokia_dev_s *priv) -{ - struct spi_dev_s *spi = priv->spi; - - /* Configure the display */ - - nokia_cmdarray(spi, sizeof(g_disctl), g_disctl); /* Display control */ - nokia_cmdarray(spi, sizeof(g_comscn), g_comscn); /* Common scan direction */ - nokia_sndcmd(spi, S1D15G10_OSCON); /* Internal oscilator ON */ - nokia_sndcmd(spi, S1D15G10_SLPOUT); /* Sleep out */ - nokia_cmdarray(spi, sizeof(g_volctr), g_volctr); /* Volume control (contrast) */ - nokia_cmdarray(spi, sizeof(g_pwrctr), g_pwrctr); /* Turn on voltage regulators */ - up_mdelay(100); -#ifdef CONFIG_NOKIA6100_INVERT - nokia_sndcmd(spi, S1D15G10_DISINV); /* Invert display */ -#else - nokia_sndcmd(spi, S1D15G10_DISNOR); /* Normal display */ -#endif - nokia_cmdarray(spi, sizeof(g_datctl), g_datctl); /* Data control */ -#if CONFIG_NOKIA6100_BPP == 8 - nokia_cmdarray(spi, sizeof(g_rgbset8), g_rgbset8); /* Set up color lookup table */ - nokia_sndcmd(spi, S1D15G10_NOP); -#endif - nokia_cmdarray(spi, sizeof(g_paset), g_paset); /* Page address set */ - nokia_cmdarray(spi, sizeof(g_paset), g_caset); /* Column address set */ - nokia_clrram(spi); - nokia_sndcmd(spi, S1D15G10_DISON); /* Display on */ - return OK; -} -#endif - -#ifdef CONFIG_NOKIA6100_PCF8833 -static int nokia_initialize(struct nokia_dev_s *priv) -{ - struct struct spi_dev_s *spi = priv->spi; - - nokia_sndcmd(spi, PCF8833_SLEEPOUT); /* Exit sleep mode */ - nokia_sndcmd(spi, PCF8833_BSTRON); /* Turn on voltage booster */ -#ifdef CONFIG_NOKIA6100_INVERT - nokia_sndcmd(spi, PCF8833_INVON); /* Invert display */ -#else - nokia_sndcmd(spi, PCF8833_INVOFF); /* Don't invert display */ -#endif - nokia_cmdarray(spi, sizeof(g_madctl), g_madctl); /* Memory data access control */ - nokia_cmdarray(spi, sizeof(g_colmod), g_colmod); /* Color interface pixel format */ - nokia_cmdarray(spi, sizeof(g_setcon), g_setcon); /* Set contrast */ - nokia_sndcmd(spi, PCF8833_NOP); /* No operation */ - nokia_clrram(spi); - nokia_sndcmd(spi, PCF8833_DISPON); /* Display on */ - return OK; -} -#endif /* CONFIG_NOKIA6100_PCF8833 */ - -/************************************************************************************** - * Public Functions - **************************************************************************************/ - -/************************************************************************************** - * Name: nokia_lcdinitialize - * - * Description: - * Initialize the NOKIA6100 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). - * - * Input Parameters: - * - * spi - A reference to the SPI driver instance. - * devno - A value in the range of 0 throuh CONFIG_NOKIA6100_NINTERFACES-1. This - * allows support for multiple LCD devices. - * - * 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 *nokia_lcdinitialize(FAR struct spi_dev_s *spi, unsigned int devno) -{ - struct nokia_dev_s *priv = &g_lcddev; - - gvdbg("Initializing\n"); - DEBUGASSERT(devno == 0); - - /* Initialize the driver data structure */ - - priv->spi = spi; /* Save the SPI instance */ - priv->contrast = NOKIA_DEFAULT_CONTRAST; /* Initial contrast setting */ - - /* Configure and enable the LCD controller */ - - nokia_configspi(spi); - if (nokia_initialize(priv) == OK) - { - /* Turn on the backlight */ - - nokia_backlight(CONFIG_NOKIA6100_BLINIT); - return &priv->dev; - } - return NULL; -} diff --git a/nuttx/drivers/lcd/p14201.c b/nuttx/drivers/lcd/p14201.c deleted file mode 100644 index 934d251ca..000000000 --- a/nuttx/drivers/lcd/p14201.c +++ /dev/null @@ -1,1246 +0,0 @@ -/************************************************************************************** - * drivers/lcd/p14201.c - * Driver for RiT P14201 series display (wih sd1329 IC controller) - * - * Copyright (C) 2010, 2012 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt <gnutt@nuttx.org> - * - * 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 written 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. - * - **************************************************************************************/ - -/************************************************************************************** - * Included Files - **************************************************************************************/ - -#include <nuttx/config.h> - -#include <sys/types.h> -#include <stdint.h> -#include <stdbool.h> -#include <string.h> -#include <errno.h> -#include <debug.h> - -#include <nuttx/arch.h> -#include <nuttx/spi.h> -#include <nuttx/lcd/lcd.h> -#include <nuttx/lcd/p14201.h> - -#include <arch/irq.h> - -#include "sd1329.h" - -#ifdef CONFIG_LCD_P14201 - -/************************************************************************************** - * Pre-processor Definitions - **************************************************************************************/ - -/* Configuration **********************************************************************/ - -/* P14201 Configuration Settings: - * - * CONFIG_P14201_SPIMODE - Controls the SPI mode - * CONFIG_P14201_FREQUENCY - Define to use a different bus frequency - * CONFIG_P14201_NINTERFACES - Specifies the number of physical P14201 devices that - * will be supported. - * CONFIG_P14201_FRAMEBUFFER - If defined, accesses will be performed using an in-memory - * copy of the OLEDs GDDRAM. This cost of this buffer is 128 * 96 / 2 = 6Kb. If this - * is defined, then the driver will be fully functional. If not, then it will have the - * following limitations: - * - * - Reading graphics memory cannot be supported, and - * - All pixel writes must be aligned to byte boundaries. - * - * The latter limitation effectively reduces the 128x96 disply to 64x96. - * - * Required LCD driver settings: - * CONFIG_LCD_P14201 - Enable P14201 support - * CONFIG_LCD_MAXCONTRAST should be 255, but any value >0 and <=255 will be accepted. - * CONFIG_LCD_MAXPOWER must be 1 - * - * Required SPI driver settings: - * CONFIG_SPI_CMDDATA - Include support for cmd/data selection. - */ - -#ifndef CONFIG_SPI_CMDDATA -# error "CONFIG_SPI_CMDDATA must be defined in your NuttX configuration" -#endif - -/* The P14201 spec says that is supports SPI mode 0,0 only. However, - * somtimes you need to tinker with these things. - */ - -#ifndef CONFIG_P14201_SPIMODE -# define CONFIG_P14201_SPIMODE SPIDEV_MODE2 -#endif - -/* CONFIG_P14201_NINTERFACES determines the number of physical interfaces - * that will be supported. - */ - -#ifndef CONFIG_P14201_NINTERFACES -# define CONFIG_P14201_NINTERFACES 1 -#endif - -#if CONFIG_P14201_NINTERFACES != 1 -# error "This implementation supports only a single OLED device" -#endif - -/* Check contrast selection */ - -#if !defined(CONFIG_LCD_MAXCONTRAST) -# define CONFIG_LCD_MAXCONTRAST 255 -#endif - -#if CONFIG_LCD_MAXCONTRAST <= 0|| CONFIG_LCD_MAXCONTRAST > 255 -# error "CONFIG_LCD_MAXCONTRAST exceeds supported maximum" -#endif - -/* Check power setting */ - -#if !defined(CONFIG_LCD_MAXPOWER) -# define CONFIG_LCD_MAXPOWER 1 -#endif - -#if CONFIG_LCD_MAXPOWER != 1 -# warning "CONFIG_LCD_MAXPOWER exceeds supported maximum" -# undef CONFIG_LCD_MAXPOWER -# define CONFIG_LCD_MAXPOWER 1 -#endif - -/* Color is 4bpp greyscale with leftmost column contained in bits 7:4 */ - -#if defined(CONFIG_NX_DISABLE_4BPP) || !defined(CONFIG_NX_PACKEDMSFIRST) -# warning "4-bit, big-endian pixel support needed" -#endif - -/* Define the CONFIG_LCD_RITDEBUG to enable detailed debug output (stuff you would - * never want to see unless you are debugging this file). - * - * Verbose debug must also be enabled - */ - -#ifndef CONFIG_DEBUG -# undef CONFIG_DEBUG_VERBOSE -# undef CONFIG_DEBUG_GRAPHICS -#endif - -#ifndef CONFIG_DEBUG_VERBOSE -# undef CONFIG_LCD_RITDEBUG -#endif - -/* Color Properties *******************************************************************/ - -/* Display Resolution */ - -#define RIT_XRES 128 -#define RIT_YRES 96 - -/* Color depth and format */ - -#define RIT_BPP 4 -#define RIT_COLORFMT FB_FMT_Y4 - -/* Default contrast */ - -#define RIT_CONTRAST ((23 * (CONFIG_LCD_MAXCONTRAST+1) / 32) - 1) - -/* Helper Macros **********************************************************************/ - -#define rit_sndcmd(p,b,l) rit_sndbytes(p,b,l,true); -#define rit_snddata(p,b,l) rit_sndbytes(p,b,l,false); - -/* Debug ******************************************************************************/ - -#ifdef CONFIG_LCD_RITDEBUG -# define ritdbg(format, arg...) vdbg(format, ##arg) -#else -# define ritdbg(x...) -#endif - -/************************************************************************************** - * Private Type Definition - **************************************************************************************/ - -/* This structure describes the state of this driver */ - -struct rit_dev_s -{ - struct lcd_dev_s dev; /* Publically visible device structure */ - FAR struct spi_dev_s *spi; /* Cached SPI device reference */ - uint8_t contrast; /* Current contrast setting */ - bool on; /* true: display is on */ -}; - -/************************************************************************************** - * Private Function Protototypes - **************************************************************************************/ - -/* Low-level SPI helpers */ - -static inline void rit_configspi(FAR struct spi_dev_s *spi); -#ifdef CONFIG_SPI_OWNBUS -static inline void rit_select(FAR struct spi_dev_s *spi); -static inline void rit_deselect(FAR struct spi_dev_s *spi); -#else -static void rit_select(FAR struct spi_dev_s *spi); -static void rit_deselect(FAR struct spi_dev_s *spi); -#endif -static void rit_sndbytes(FAR struct rit_dev_s *priv, FAR const uint8_t *buffer, - size_t buflen, bool cmd); -static void rit_sndcmds(FAR struct rit_dev_s *priv, FAR const uint8_t *table); - -/* LCD Data Transfer Methods */ - -static int rit_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer, - size_t npixels); -static int rit_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer, - size_t npixels); - -/* LCD Configuration */ - -static int rit_getvideoinfo(FAR struct lcd_dev_s *dev, - FAR struct fb_videoinfo_s *vinfo); -static int rit_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planeno, - FAR struct lcd_planeinfo_s *pinfo); - -/* LCD RGB Mapping */ - -#ifdef CONFIG_FB_CMAP -# error "RGB color mapping not supported by this driver" -#endif - -/* Cursor Controls */ - -#ifdef CONFIG_FB_HWCURSOR -# error "Cursor control not supported by this driver" -#endif - -/* LCD Specific Controls */ - -static int rit_getpower(struct lcd_dev_s *dev); -static int rit_setpower(struct lcd_dev_s *dev, int power); -static int rit_getcontrast(struct lcd_dev_s *dev); -static int rit_setcontrast(struct lcd_dev_s *dev, unsigned int contrast); - -/************************************************************************************** - * Private Data - **************************************************************************************/ - -/* This is working memory allocated by the LCD driver for each LCD device - * and for each color plane. This memory will hold one raster line of data. - * The size of the allocated run buffer must therefore be at least - * (bpp * xres / 8). Actual alignment of the buffer must conform to the - * bitwidth of the underlying pixel type. - * - * If there are multiple planes, they may share the same working buffer - * because different planes will not be operate on concurrently. However, - * if there are multiple LCD devices, they must each have unique run buffers. - */ - -static uint8_t g_runbuffer[RIT_XRES / 2]; - -/* CONFIG_P14201_FRAMEBUFFER - If defined, accesses will be performed using an in-memory - * copy of the OLEDs GDDRAM. This cost of this buffer is 128 * 64 / 2 = 4Kb. If this - * is defined, then the driver will be full functional. If not, then: - * - * - Reading graphics memory cannot be supported, and - * - All pixel writes must be aligned to byte boundaries. - */ - -#ifdef CONFIG_P14201_FRAMEBUFFER -static uint8_t g_framebuffer[RIT_YRES * RIT_XRES / 2]; -#endif - -/* This structure describes the overall LCD video controller */ - -static const struct fb_videoinfo_s g_videoinfo = -{ - .fmt = RIT_COLORFMT, /* Color format: RGB16-565: RRRR RGGG GGGB BBBB */ - .xres = RIT_XRES, /* Horizontal resolution in pixel columns */ - .yres = RIT_YRES, /* Vertical resolution in pixel rows */ - .nplanes = 1, /* Number of color planes supported */ -}; - -/* This is the standard, NuttX Plane information object */ - -static const struct lcd_planeinfo_s g_planeinfo = -{ - .putrun = rit_putrun, /* Put a run into LCD memory */ - .getrun = rit_getrun, /* Get a run from LCD memory */ - .buffer = (uint8_t*)g_runbuffer, /* Run scratch buffer */ - .bpp = RIT_BPP, /* Bits-per-pixel */ -}; - -/* This is the OLED driver instance (only a single device is supported for now) */ - -static struct rit_dev_s g_oleddev = -{ - .dev = - { - /* LCD Configuration */ - - .getvideoinfo = rit_getvideoinfo, - .getplaneinfo = rit_getplaneinfo, - - /* LCD RGB Mapping -- Not supported */ - /* Cursor Controls -- Not supported */ - - /* LCD Specific Controls */ - - .getpower = rit_getpower, - .setpower = rit_setpower, - .getcontrast = rit_getcontrast, - .setcontrast = rit_setcontrast, - }, -}; - -/* A table of magic initialization commands. This initialization sequence is - * derived from RiT Application Note for the P14201 (with a few tweaked values - * as discovered in some Luminary code examples). - */ - -static const uint8_t g_initcmds[] = -{ - 3, SSD1329_CMD_LOCK, /* Set lock command */ - SSD1329_LOCK_OFF, /* Disable locking */ - SSD1329_NOOP, - 2, SSD1329_SLEEP_ON, /* Matrix display OFF */ - SSD1329_NOOP, - 3, SSD1329_ICON_ALL, /* Set all ICONs to OFF */ - SSD1329_ICON_OFF, /* OFF selection */ - SSD1329_NOOP, - 3, SSD1329_MUX_RATIO, /* Set MUX ratio */ - 95, /* 96 MUX */ - SSD1329_NOOP, - 3, SSD1329_SET_CONTRAST, /* Set contrast */ - RIT_CONTRAST, /* Default contrast */ - SSD1329_NOOP, - 3, SSD1329_PRECHRG2_SPEED, /* Set second pre-charge speed */ - (31 << 1) | SSD1329_PRECHRG2_DBL, /* Pre-charge speed == 32, doubled */ - SSD1329_NOOP, - 3, SSD1329_GDDRAM_REMAP, /* Set GDDRAM re-map */ - (SSD1329_COM_SPLIT| /* Enable COM slip even/odd */ - SSD1329_COM_REMAP| /* Enable COM re-map */ - SSD1329_NIBBLE_REMAP), /* Enable nibble re-map */ - SSD1329_NOOP, - 3, SSD1329_VERT_START, /* Set Display Start Line */ - 0, /* Line = 0 */ - SSD1329_NOOP, - 3, SSD1329_VERT_OFFSET, /* Set Display Offset */ - 0, /* Offset = 0 */ - SSD1329_NOOP, - 2, SSD1329_DISP_NORMAL, /* Display mode normal */ - SSD1329_NOOP, - 3, SSD1329_PHASE_LENGTH, /* Set Phase Length */ - 1 | /* Phase 1 period = 1 DCLK */ - (1 << 4), /* Phase 2 period = 1 DCLK */ - SSD1329_NOOP, - 3, SSD1329_FRAME_FREQ, - 35, /* 35 DCLK's per row */ - SSD1329_NOOP, - 3, SSD1329_DCLK_DIV, /* Set Front Clock Divider / Oscillator Frequency */ - 2 | /* Divide ration = 3 */ - (14 << 4), /* Oscillator Frequency, FOSC, setting */ - SSD1329_NOOP, - 17, SSD1329_GSCALE_LOOKUP, /* Look Up Table for Gray Scale Pulse width */ - 1, 2, 3, 4, 5, /* Value for GS1-5 level Pulse width */ - 6, 8, 10, 12, 14, /* Value for GS6-10 level Pulse width */ - 16, 19, 22, 26, 30, /* Value for GS11-15 level Pulse width */ - SSD1329_NOOP, - 3, SSD1329_PRECHRG2_PERIOD, /* Set Second Pre-charge Period */ - 1, /* 1 DCLK */ - SSD1329_NOOP, - 3, SSD1329_PRECHRG1_VOLT, /* Set First Precharge voltage, VP */ - 0x3f, /* 1.00 x Vcc */ - SSD1329_NOOP, - 0 /* Zero length command terminates table */ -}; - -/* Turn the maxtrix display on (sleep mode off) */ - -static const uint8_t g_sleepoff[] = -{ - SSD1329_SLEEP_OFF, /* Matrix display ON */ - SSD1329_NOOP, -}; - -/* Turn the maxtrix display off (sleep mode on) */ - -static const uint8_t g_sleepon[] = -{ - SSD1329_SLEEP_ON, /* Matrix display OFF */ - SSD1329_NOOP, -}; - -/* Set horizontal increment mode */ - -static const uint8_t g_horzinc[] = -{ - SSD1329_GDDRAM_REMAP, - (SSD1329_COM_SPLIT|SSD1329_COM_REMAP|SSD1329_NIBBLE_REMAP), -}; - -/* The following set a window that covers the entire display */ - -static const uint8_t g_setallcol[] = -{ - SSD1329_SET_COLADDR, - 0, - (RIT_XRES/2)-1 -}; - -static const uint8_t g_setallrow[] = -{ - SSD1329_SET_ROWADDR, - 0, - RIT_YRES-1 -}; - -/************************************************************************************** - * Private Functions - **************************************************************************************/ - -/************************************************************************************** - * Name: rit_configspi - * - * Description: - * Configure the SPI for use with the P14201 - * - * Input Parameters: - * spi - Reference to the SPI driver structure - * - * Returned Value: - * None - * - * Assumptions: - * - **************************************************************************************/ - -static inline void rit_configspi(FAR struct spi_dev_s *spi) -{ -#ifdef CONFIG_P14201_FREQUENCY - ritdbg("Mode: %d Bits: 8 Frequency: %d\n", - CONFIG_P14201_SPIMODE, CONFIG_P14201_FREQUENCY); -#else - ritdbg("Mode: %d Bits: 8\n", CONFIG_P14201_SPIMODE); -#endif - - /* Configure SPI for the P14201. But only if we own the SPI bus. Otherwise, don't - * bother because it might change. - */ - -#ifdef CONFIG_SPI_OWNBUS - SPI_SETMODE(spi, CONFIG_P14201_SPIMODE); - SPI_SETBITS(spi, 8); -#ifdef CONFIG_P14201_FREQUENCY - SPI_SETFREQUENCY(spi, CONFIG_P14201_FREQUENCY) -#endif -#endif -} - -/************************************************************************************** - * Name: rit_select - * - * Description: - * Select the SPI, locking and re-configuring if necessary - * - * Input Parameters: - * spi - Reference to the SPI driver structure - * - * Returned Value: - * None - * - * Assumptions: - * - **************************************************************************************/ - -#ifdef CONFIG_SPI_OWNBUS -static inline void rit_select(FAR struct spi_dev_s *spi) -{ - /* We own the SPI bus, so just select the chip */ - - SPI_SELECT(spi, SPIDEV_DISPLAY, true); -} -#else -static void rit_select(FAR struct spi_dev_s *spi) -{ - /* Select P14201 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, true); - - /* Now make sure that the SPI bus is configured for the P14201 (it - * might have gotten configured for a different device while unlocked) - */ - - SPI_SETMODE(spi, CONFIG_P14201_SPIMODE); - SPI_SETBITS(spi, 8); -#ifdef CONFIG_P14201_FREQUENCY - SPI_SETFREQUENCY(spi, CONFIG_P14201_FREQUENCY); -#endif -} -#endif - -/************************************************************************************** - * Name: rit_deselect - * - * Description: - * De-select the SPI - * - * Input Parameters: - * spi - Reference to the SPI driver structure - * - * Returned Value: - * None - * - * Assumptions: - * - **************************************************************************************/ - -#ifdef CONFIG_SPI_OWNBUS -static inline void rit_deselect(FAR struct spi_dev_s *spi) -{ - /* We own the SPI bus, so just de-select the chip */ - - SPI_SELECT(spi, SPIDEV_DISPLAY, false); -} -#else -static void rit_deselect(FAR struct spi_dev_s *spi) -{ - /* De-select P14201 chip and relinquish the SPI bus. */ - - SPI_SELECT(spi, SPIDEV_DISPLAY, false); - SPI_LOCK(spi, false); -} -#endif - -/************************************************************************************** - * Name: rit_sndbytes - * - * Description: - * Send a sequence of command or data bytes to the SSD1329 controller. - * - * Input Parameters: - * spi - Reference to the SPI driver structure - * buffer - A reference to memory containing the command bytes to be sent. - * buflen - The number of command bytes in buffer to be sent - * - * Returned Value: - * None - * - * Assumptions: - * The caller as selected the OLED device. - * - **************************************************************************************/ - -static void rit_sndbytes(FAR struct rit_dev_s *priv, FAR const uint8_t *buffer, - size_t buflen, bool cmd) -{ - FAR struct spi_dev_s *spi = priv->spi; - uint8_t tmp; - - ritdbg("buflen: %d cmd: %s [%02x %02x %02x]\n", - buflen, cmd ? "YES" : "NO", buffer[0], buffer[1], buffer[2] ); - DEBUGASSERT(spi); - - /* Clear/set the D/Cn bit to enable command or data mode */ - - (void)SPI_CMDDATA(spi, SPIDEV_DISPLAY, cmd); - - /* Loop until the entire command/data block is transferred */ - - while (buflen-- > 0) - { - /* Write the next byte to the controller */ - - tmp = *buffer++; - (void)SPI_SEND(spi, tmp); - } -} - -/************************************************************************************** - * Name: rit_sndcmd - * - * Description: - * Send multiple commands from a table of commands. - * - * Input Parameters: - * spi - Reference to the SPI driver structure - * table - A reference to table containing all of the commands to be sent. - * - * Returned Value: - * None - * - * Assumptions: - * - **************************************************************************************/ - -static void rit_sndcmds(FAR struct rit_dev_s *priv, FAR const uint8_t *table) -{ - int cmdlen; - - /* Table terminates with a zero length command */ - - while ((cmdlen = *table++) != 0) - { - ritdbg("command: %02x cmdlen: %d\n", *table, cmdlen); - rit_sndcmd(priv, table, cmdlen); - table += cmdlen; - } -} - -/************************************************************************************** - * Name: rit_clear - * - * Description: - * This method can be used to clear the entire display. - * - * Input Parameters: - * priv - Reference to private driver structure - * - * Assumptions: - * Caller has selected the OLED section. - * - **************************************************************************************/ - -#ifdef CONFIG_P14201_FRAMEBUFFER -static inline void rit_clear(FAR struct rit_dev_s *priv) -{ - FAR uint8_t *ptr = g_framebuffer; - unsigned int row; - - ritdbg("Clear display\n"); - - /* Initialize the framebuffer */ - - memset(g_framebuffer, (RIT_Y4_BLACK << 4) | RIT_Y4_BLACK, RIT_YRES * RIT_XRES / 2); - - /* Set a window to fill the entire display */ - - rit_sndcmd(priv, g_setallcol, sizeof(g_setallcol)); - rit_sndcmd(priv, g_setallrow, sizeof(g_setallrow)); - rit_sndcmd(priv, g_horzinc, sizeof(g_horzinc)); - - /* Display each row */ - - for(row = 0; row < RIT_YRES; row++) - { - /* Display a horizontal run */ - - rit_snddata(priv, ptr, RIT_XRES / 2); - ptr += RIT_XRES / 2; - } -} -#else -static inline void rit_clear(FAR struct rit_dev_s *priv) -{ - unsigned int row; - - ritdbg("Clear display\n"); - - /* Create a black row */ - - memset(g_runbuffer, (RIT_Y4_BLACK << 4) | RIT_Y4_BLACK, RIT_XRES / 2); - - /* Set a window to fill the entire display */ - - rit_sndcmd(priv, g_setallcol, sizeof(g_setallcol)); - rit_sndcmd(priv, g_setallrow, sizeof(g_setallrow)); - rit_sndcmd(priv, g_horzinc, sizeof(g_horzinc)); - - /* Display each row */ - - for(row = 0; row < RIT_YRES; row++) - { - /* Display a horizontal run */ - - rit_snddata(priv, g_runbuffer, RIT_XRES / 2); - } -} -#endif - -/************************************************************************************** - * Name: rit_putrun - * - * Description: - * This method can be used to write a partial raster line to the LCD. - * - * Input Parameters: - * row - Starting row to write to (range: 0 <= row < yres) - * col - Starting column to write to (range: 0 <= col <= xres-npixels) - * buffer - The buffer containing the run to be written to the LCD - * npixels - The number of pixels to write to the LCD - * (range: 0 < npixels <= xres-col) - * - **************************************************************************************/ - -#ifdef CONFIG_P14201_FRAMEBUFFER -static int rit_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer, - size_t npixels) -{ - FAR struct rit_dev_s *priv = (FAR struct rit_dev_s *)&g_oleddev; - uint8_t cmd[3]; - uint8_t *run; - int start; - int end; - int aend; - int i; - - ritdbg("row: %d col: %d npixels: %d\n", row, col, npixels); - DEBUGASSERT(buffer); - - /* Toss out the special case of the empty run now */ - - if (npixels < 1) - { - return OK; - } - - /* Get the beginning of the line containing run in the framebuffer */ - - run = g_framebuffer + row * RIT_XRES / 2; - - /* Get the starting and ending byte offsets containing the run. - * the run starts at &run[start] and continues through run[end-1]. - * However, the first and final pixels at these locations may - * not be byte aligned. - */ - - start = col >> 1; - aend = (col + npixels) >> 1; - end = (col + npixels + 1) >> 1; - ritdbg("start: %d aend: %d end: %d\n", start, aend, end); - - /* Copy the run into the framebuffer, handling nibble alignment. - * - * CASE 1: First pixel X position is byte aligned - * - * example col=6 npixels = 8 example col=6 npixels=7 - * - * Run: |AB|AB|AB|AB| |AB|AB|AB|AB| - * GDDRAM row: - * Byte | 0| 1| 2| 3| 4| 5| 6| | 0| 1| 2| 3| 4| 5| 6| - * Pixel: |--|--|--|AB|AB|AB|AB| |--|--|--|AB|AB|AB|A-| - * - * start = 3 start = 3 - * aend = 6 aend = 6 - * end = 6 end = 7 - * - */ - - if ((col & 1) == 0) - { - /* Check for the special case of only 1 pixel being blitted */ - - if (npixels > 1) - { - /* Beginning of buffer is properly aligned, from start to aend */ - - memcpy(&run[start], buffer, aend - start); - } - - /* An even number of byte-aligned pixel pairs have been written (where - * zero counts as an even number). If npixels was was odd (including - * npixels == 1), then handle the final, byte aligned pixel. - */ - - if (aend != end) - { - /* The leftmost column is contained in source bits 7:4 and in - * destination bits 7:4 - */ - - run[aend] = (run[aend] & 0x0f) | (buffer[aend - start] & 0xf0); - } - } - - /* CASE 2: First pixel X position is byte aligned - * - * example col=7 npixels = 8 example col=7 npixels=7 - * - * Run: |AB|AB|AB|AB| |AB|AB|AB|AB| - * GDDRAM row: - * Byte | 0| 1| 2| 3| 4| 5| 6| 7| | 0| 1| 2| 3| 4| 5| 6| - * Pixel: |--|--|--|-A|BA|BA|BA|B-| |--|--|--|-A|BA|BA|BA| - * - * start = 3 start = 3 - * aend = 7 aend = 7 - * end = 8 end = 7 - */ - - else - { - uint8_t curr = buffer[0]; - uint8_t last; - - /* Handle the initial unaligned pixel. Source bits 7:4 into - * destination bits 3:0. In the special case of npixel == 1, - * this finished the job. - */ - - run[start] = (run[start] & 0xf0) | (curr >> 4); - - /* Now construct the rest of the bytes in the run (possibly special - * casing the final, partial byte below). - */ - - for (i = start + 1; i < aend; i++) - { - /* bits 3:0 from previous byte to run bits 7:4; - * bits 7:4 of current byte to run bits 3:0 - */ - - last = curr; - curr = buffer[i-start]; - run[i] = (last << 4) | (curr >> 4); - } - - /* An odd number of unaligned pixel have been written (where npixels - * may have been as small as one). If npixels was was even, then handle - * the final, unaligned pixel. - */ - - if (aend != end) - { - /* The leftmost column is contained in source bits 3:0 and in - * destination bits 7:4 - */ - - run[aend] = (run[aend] & 0x0f) | (curr << 4); - } - } - - /* Select the SD1329 controller */ - - rit_select(priv->spi); - - /* Setup a window that describes a run starting at the specified column - * and row, and ending at the column + npixels on the same row. - */ - - cmd[0] = SSD1329_SET_COLADDR; - cmd[1] = start; - cmd[2] = end - 1; - rit_sndcmd(priv, cmd, 3); - - cmd[0] = SSD1329_SET_ROWADDR; - cmd[1] = row; - cmd[2] = row; - rit_sndcmd(priv, cmd, 3); - - /* Write the run to GDDRAM. */ - - rit_sndcmd(priv, g_horzinc, sizeof(g_horzinc)); - rit_snddata(priv, &run[start], end - start); - - /* De-select the SD1329 controller */ - - rit_deselect(priv->spi); - return OK; -} -#else -static int rit_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer, - size_t npixels) -{ - FAR struct rit_dev_s *priv = (FAR struct rit_dev_s *)&g_oleddev; - uint8_t cmd[3]; - - ritdbg("row: %d col: %d npixels: %d\n", row, col, npixels); - DEBUGASSERT(buffer); - - if (npixels > 0) - { - /* Check that the X and Y coordinates are within range */ - - DEBUGASSERT(col < RIT_XRES && (col + npixels) <= RIT_XRES && row < RIT_YRES); - - /* Check that the X coordinates are aligned to 8-bit boundaries - * (this needs to get fixed somehow) - */ - - DEBUGASSERT((col & 1) == 0 && (npixels & 1) == 0); - - /* Select the SD1329 controller */ - - rit_select(priv->spi); - - /* Setup a window that describes a run starting at the specified column - * and row, and ending at the column + npixels on the same row. - */ - - cmd[0] = SSD1329_SET_COLADDR; - cmd[1] = col >> 1; - cmd[2] = ((col + npixels) >> 1) - 1; - rit_sndcmd(priv, cmd, 3); - - cmd[0] = SSD1329_SET_ROWADDR; - cmd[1] = row; - cmd[2] = row; - rit_sndcmd(priv, cmd, 3); - - /* Write the run to GDDRAM. */ - - rit_sndcmd(priv, g_horzinc, sizeof(g_horzinc)); - rit_snddata(priv, buffer, npixels >> 1); - - /* De-select the SD1329 controller */ - - rit_deselect(priv->spi); - } - - return OK; -} -#endif - -/************************************************************************************** - * Name: rit_getrun - * - * Description: - * This method can be used to read a partial raster line from the LCD: - * - * 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) - * - **************************************************************************************/ - -#ifdef CONFIG_P14201_FRAMEBUFFER -static int rit_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer, - size_t npixels) -{ - uint8_t *run; - int start; - int end; - int aend; - int i; - - ritdbg("row: %d col: %d npixels: %d\n", row, col, npixels); - DEBUGASSERT(buffer); - - /* Can't read from OLED GDDRAM in SPI mode, but we can read from the framebuffer */ - /* Toss out the special case of the empty run now */ - - if (npixels < 1) - { - return OK; - } - - /* Get the beginning of the line containing run in the framebuffer */ - - run = g_framebuffer + row * RIT_XRES / 2; - - /* Get the starting and ending byte offsets containing the run. - * the run starts at &run[start] and continues through run[end-1]. - * However, the first and final pixels at these locations may - * not be byte aligned (see examples in putrun()). - */ - - start = col >> 1; - aend = (col + npixels) >> 1; - end = (col + npixels + 1) >> 1; - - /* Copy the run into the framebuffer, handling nibble alignment */ - - if ((col & 1) == 0) - { - /* Check for the special case of only 1 pixels being copied */ - - if (npixels > 1) - { - /* Beginning of buffer is properly aligned, from start to aend */ - - memcpy(buffer, &run[start], aend - start + 1); - } - - /* Handle any final pixel (including the special case where npixels == 1). */ - - if (aend != end) - { - /* The leftmost column is contained in source bits 7:4 and in - * destination bits 7:4 - */ - - buffer[aend - start] = run[aend] & 0xf0; - } - } - else - { - uint8_t curr = run[start]; - uint8_t last; - - /* Now construct the rest of the bytes in the run (possibly special - * casing the final, partial byte below). - */ - - for (i = start + 1; i < aend; i++) - { - /* bits 3:0 from previous byte to run bits 7:4; - * bits 7:4 of current byte to run bits 3:0 - */ - - last = curr; - curr = run[i]; - *buffer++ = (last << 4) | (curr >> 4); - } - - /* Handle any final pixel (including the special case where npixels == 1). */ - - if (aend != end) - { - /* The leftmost column is contained in source bits 3:0 and in - * destination bits 7:4 - */ - - *buffer = (curr << 4); - } - } - - return OK; -} -#else -static int rit_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer, - size_t npixels) -{ - /* Can't read from OLED GDDRAM in SPI mode */ - - return -ENOSYS; -} -#endif - -/************************************************************************************** - * Name: rit_getvideoinfo - * - * Description: - * Get information about the LCD video controller configuration. - * - **************************************************************************************/ - -static int rit_getvideoinfo(FAR struct lcd_dev_s *dev, - FAR struct fb_videoinfo_s *vinfo) -{ - DEBUGASSERT(dev && vinfo); - gvdbg("fmt: %d xres: %d yres: %d nplanes: %d\n", - g_videoinfo.fmt, g_videoinfo.xres, g_videoinfo.yres, g_videoinfo.nplanes); - memcpy(vinfo, &g_videoinfo, sizeof(struct fb_videoinfo_s)); - return OK; -} - -/************************************************************************************** - * Name: rit_getplaneinfo - * - * Description: - * Get information about the configuration of each LCD color plane. - * - **************************************************************************************/ - -static int rit_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planeno, - FAR struct lcd_planeinfo_s *pinfo) -{ - DEBUGASSERT(pinfo && planeno == 0); - gvdbg("planeno: %d bpp: %d\n", planeno, g_planeinfo.bpp); - memcpy(pinfo, &g_planeinfo, sizeof(struct lcd_planeinfo_s)); - return OK; -} - -/************************************************************************************** - * Name: rit_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. - * - **************************************************************************************/ - -static int rit_getpower(FAR struct lcd_dev_s *dev) -{ - FAR struct rit_dev_s *priv = (FAR struct rit_dev_s *)dev; - DEBUGASSERT(priv); - - gvdbg("power: %s\n", priv->on ? "ON" : "OFF"); - return priv->on ? CONFIG_LCD_MAXPOWER : 0; -} - -/************************************************************************************** - * Name: rit_setpower - * - * Description: - * Enable/disable LCD panel power (0: full off - CONFIG_LCD_MAXPOWER: full on). On - * backlit LCDs, this setting may correspond to the backlight setting. - * - **************************************************************************************/ - -static int rit_setpower(struct lcd_dev_s *dev, int power) -{ - struct rit_dev_s *priv = (struct rit_dev_s *)dev; - DEBUGASSERT(priv && (unsigned)power <= CONFIG_LCD_MAXPOWER && priv->spi); - - gvdbg("power: %d\n", power); - - /* Select the SD1329 controller */ - - rit_select(priv->spi); - - /* Only two power settings -- 0: sleep on, 1: sleep off */ - - if (power > 0) - { - /* Re-initialize the SSD1329 controller */ - - rit_sndcmds(priv, g_initcmds); - - /* Take the display out of sleep mode */ - - rit_sndcmd(priv, g_sleepoff, sizeof(g_sleepoff)); - priv->on = true; - } - else - { - /* Put the display into sleep mode */ - - rit_sndcmd(priv, g_sleepon, sizeof(g_sleepon)); - priv->on = false; - } - - /* De-select the SD1329 controller */ - - rit_deselect(priv->spi); - return OK; -} - -/************************************************************************************** - * Name: rit_getcontrast - * - * Description: - * Get the current contrast setting (0-CONFIG_LCD_MAXCONTRAST). - * - **************************************************************************************/ - -static int rit_getcontrast(struct lcd_dev_s *dev) -{ - struct rit_dev_s *priv = (struct rit_dev_s *)dev; - - gvdbg("contrast: %d\n", priv->contrast); - return priv->contrast; -} - -/************************************************************************************** - * Name: rit_setcontrast - * - * Description: - * Set LCD panel contrast (0-CONFIG_LCD_MAXCONTRAST). - * - **************************************************************************************/ - -static int rit_setcontrast(struct lcd_dev_s *dev, unsigned int contrast) -{ - struct rit_dev_s *priv = (struct rit_dev_s *)dev; - uint8_t cmd[3]; - - gvdbg("contrast: %d\n", contrast); - DEBUGASSERT(contrast <= CONFIG_LCD_MAXCONTRAST); - - /* Select the SD1329 controller */ - - rit_select(priv->spi); - - /* Set new contrast */ - - cmd[0] = SSD1329_SET_CONTRAST; - cmd[1] = contrast; - cmd[2] = SSD1329_NOOP; - rit_sndcmd(priv, cmd, 3); - - /* De-select the SD1329 controller */ - - rit_deselect(priv->spi); - priv->contrast = contrast; - return OK; -} - -/************************************************************************************** - * Public Functions - **************************************************************************************/ - -/************************************************************************************** - * Name: rit_initialize - * - * Description: - * Initialize the P14201 video hardware. The initial state of the OLED is fully - * initialized, display memory cleared, and the OLED ready to use, but with the power - * setting at 0 (full off == sleep mode). - * - * Input Parameters: - * spi - A reference to the SPI driver instance. - * devno - A value in the range of 0 throuh CONFIG_P14201_NINTERFACES-1. This allows - * support for multiple OLED devices. - * - * Returned Value: - * On success, this function returns a reference to the LCD object for the specified - * OLED. NULL is returned on any failure. - * - **************************************************************************************/ - -FAR struct lcd_dev_s *rit_initialize(FAR struct spi_dev_s *spi, unsigned int devno) -{ - FAR struct rit_dev_s *priv = (FAR struct rit_dev_s *)&g_oleddev; - DEBUGASSERT(devno == 0 && spi); - - gvdbg("Initializing devno: %d\n", devno); - - /* Driver state data */ - - priv->spi = spi; - priv->contrast = RIT_CONTRAST; - priv->on = false; - - /* Select the SD1329 controller */ - - rit_configspi(spi); - rit_select(spi); - - /* Clear the display */ - - rit_clear(priv); - - /* Configure (but don't enable) the OLED */ - - rit_sndcmds(priv, g_initcmds); - - /* De-select the SD1329 controller */ - - rit_deselect(spi); - return &priv->dev; -} -#endif /* CONFIG_LCD_P14201 */ diff --git a/nuttx/drivers/lcd/pcf8833.h b/nuttx/drivers/lcd/pcf8833.h deleted file mode 100644 index 36dc65ac3..000000000 --- a/nuttx/drivers/lcd/pcf8833.h +++ /dev/null @@ -1,152 +0,0 @@ -/************************************************************************************** - * drivers/lcd/pcf8833.h - * Definitions for the Phillips PCF8833 LCD controller - * - * Copyright (C) 2010 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt <gnutt@nuttx.org> - * - * References: "Data Sheet, PCF8833 STN RGB 132x132x3 driver," Phillips, 2003 Feb 14. - * - * 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 written 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. - * - **************************************************************************************/ - -#ifndef __DRIVERS_LCD_PCF8833_H -#define __DRIVERS_LCD_PCF8833_H - -/************************************************************************************** - * Included Files - **************************************************************************************/ - -/************************************************************************************** - * Pre-processor Definitions - **************************************************************************************/ -/* Pixel format codes */ - -#define PCF8833_FMT_8BPS (2) -#define PCF8833_FMT_12BPS (3) -#define PCF8833_FMT_16BPS (5) - -/* LCD Commands */ - -#define PCF8833_NOP 0x00 /* No operation; Data: none */ -#define PCF8833_SWRESET 0x01 /* Software reset ; Data: none */ -#define PCF8833_BSTROFF 0x02 /* Booster voltage off; Data: none */ -#define PCF8833_BSTRON 0x03 /* Booster voltage on; Data: none */ -#define PCF8833_RDDIDIF 0x04 /* Read display identification; Data: none */ -#define PCF8833_RDDST 0x09 /* Read display status; Data: none */ -#define PCF8833_SLEEPIN 0x10 /* Sleep_IN; Data: none */ -#define PCF8833_SLEEPOUT 0x11 /* Sleep_OUT; Data: none */ -#define PCF8833_PTLON 0x12 /* Partial mode on; Data: none */ -#define PCF8833_NORON 0x13 /* Normal Display mode on; Data: none */ -#define PCF8833_INVOFF 0x20 /* Display inversion off; Data: none */ -#define PCF8833_INVON 0x21 /* Display inversion on; Data: none */ -#define PCF8833_DALO 0x22 /* All pixel off; Data: none */ -#define PCF8833_DAL 0x23 /* All pixel on; Data: none */ -#define PCF8833_SETCON 0x25 /* Set contrast; Data: (1) contrast */ -#define PCF8833_DISPOFF 0x28 /* Display off; Data: none */ -#define PCF8833_DISPON 0x29 /* Display on; Data: none */ -#define PCF8833_CASET 0x2a /* Column address set; Data: (1) X start (2) X end */ -#define PCF8833_PASET 0x2b /* Page address set Data: (1) Y start (2) Y end */ -#define PCF8833_RAMWR 0x2c /* Memory write; Data: (1) write data */ -#define PCF8833_RGBSET 0x2d /* Colour set; Data: (1-8) red tones, (9-16) green tones, (17-20) blue tones */ -#define PCF8833_PTLAR 0x30 /* Partial area; Data: (1) start address (2) end address */ -#define PCF8833_VSCRDEF 0x33 /* Vertical scroll definition; Data: (1) top fixed, (2) scrol area, (3) bottom fixed */ -#define PCF8833_TEOFF 0x34 /* Tearing line off; Data: none */ -#define PCF8833_TEON 0x35 /* Tearing line on; Data: (1) don't care */ -#define PCF8833_MADCTL 0x36 /* Memory data access control; Data: (1) access control settings */ -#define PCF8833_SEP 0x37 /* Set Scroll Entry Point; Data: (1) scroll entry point */ -#define PCF8833_IDMOFF 0x38 /* Idle mode off; Data: none */ -#define PCF8833_IDMON 0x39 /* Idle mode on; Data: none */ -#define PCF8833_COLMOD 0x3a /* Interface pixel format; Data: (1) color interface format */ -#define PCF8833_SETVOP 0xb0 /* Set VOP; Data: (1) VOP5-8 (2) VOP0-4 */ -#define PCF8833_BRS 0xb4 /* Bottom Row Swap; Data: none */ -#define PCF8833_TRS 0xb6 /* Top Row Swap; Data: none */ -#define PCF8833_FINV 0xb9 /* Super Frame INVersion; Data: none */ -#define PCF8833_DOR 0xba /* Data ORder; Data: none */ -#define PCF8833_TCDFE 0xbd /* Enable/disable DF temp comp; Data: none */ -#define PCF8833_TCVOPE 0xbf /* Enable or disable VOP temp comp; Data: none */ -#define PCF8833_EC 0xc0 /* Internal or external oscillator; Data: none */ -#define PCF8833_SETMUL 0xc2 /* Set multiplication factor; Data: (1) Multiplication factor */ -#define PCF8833_TCVOPAB 0xc3 /* Set TCVOP slopes A and B; Data: (1) SLB and SLA */ -#define PCF8833_TCVOPCD 0xc4 /* Set TCVOP slopes C and D; Data: (1) SLD and SLC */ -#define PCF8833_TCDF 0xc5 /* Set divider frequency; Data: Divider factor in region (1) A (2) B (3) C (4) D */ -#define PCF8833_DF8COLOR 0xc6 /* Set divider frequency 8-colour mode; Data: (1) DF80-6 */ -#define PCF8833_SETBS 0xc7 /* Set bias system; Data: (1) Bias systems */ -#define PCF8833_RDTEMP 0xc8 /* Temperature read back; Data: none */ -#define PCF8833_NLI 0xc9 /* N-Line Inversion; Data: (1) NLI time slots invervsion */ -#define PCF8833_RDID1 0xda /* Read ID1; Data: none */ -#define PCF8833_RDID2 0xdb /* Read ID2; Data: none */ -#define PCF8833_RDID3 0xdc /* Read ID3; Data: none */ -#define PCF8833_SFD 0xef /* Select factory defaults; Data: none */ -#define PCF8833_ECM 0xf0 /* Enter Calibration mode; Data: (1) Calibration control settings */ -#define PCF8833_OTPSHTIN 0xf1 /* Shift data in OTP shift registers; Data: Any number of bytes */ - -/* Memory data access control (MADCTL) bit definitions */ - -#define MADCTL_RGB (1 << 3) /* Bit 3: BGR */ -#define MADCTL_LAO (1 << 4) /* Bit 4: Line address order bottom to top */ -#define MADCTL_V (1 << 5) /* Bit 5: Vertical RAM write; in Y direction */ -#define MADCTL_MX (1 << 6) /* Bit 6: Mirror X */ -#define MADCTL_MY (1 << 7) /* Bit 7: Mirror Y */ - -/* PCF8833 status register bit definitions */ -/* CMD format: RDDST command followed by four status bytes: */ -/* Byte 1: D31 d30 D29 D28 D27 D26 --- --- */ - -#define PCF8833_ST_RGB (1 << 2) /* Bit 2: D26 - RGB/BGR order */ -#define PCF8833_ST_LINEADDR (1 << 3) /* Bit 3: D27 - Line address order */ -#define PCF8833_ST_ADDRMODE (1 << 4) /* Bit 4: D28 - Vertical/horizontal addressing mode */ -#define PCF8833_ST_XADDR (1 << 5) /* Bit 5: D29 - X address order */ -#define PCF8833_ST_YADDR (1 << 6) /* Bit 6: D30 - Y address order */ -#define PCF8833_ST_BOOSTER (1 << 7) /* Bit 7: D31 - Booster voltage status */ - -/* Byte 2: --- D22 D21 D20 D19 D18 D17 D16 */ - -#define PCF8833_ST_NORMAL (1 << 0) /* Bit 0: D16 - Normal display mode */ -#define PCF8833_ST_SLEEPIN (1 << 1) /* Bit 1: D17 - Sleep in selected */ -#define PCF8833_ST_PARTIAL (1 << 2) /* Bit 2: D18 - Partial mode on */ -#define PCF8833_ST_IDLE (1 << 3) /* Bit 3: D19 - Idle mode selected */ -#define PCF8833_ST_PIXELFMT_SHIFT (4) /* Bits 4-6: D20-D22 - Interface pixel format */ -#define PCF8833_ST_PIXELFMT_MASK (7 << PCF8833_ST_PIXELFMT_SHIFT) -# define PCF8833_ST_PIXELFMT_8BPS (PCF8833_FMT_8BPS << PCF8833_ST_PIXELFMT_SHIFT) -# define PCF8833_ST_PIXELFMT_12BPS (PCF8833_FMT_12BPS << PCF8833_ST_PIXELFMT_SHIFT) -# define PCF8833_ST_PIXELFMT_16BPS (PCF8833_FMT_16BPS << PCF8833_ST_PIXELFMT_SHIFT) - -/* Byte 3: D15 -- D13 D12 D11 D10 D9 --- */ - -#define PCF8833_ST_TEARING (1 << 1) /* Bit 1: D9 - Tearing effect on */ -#define PCF8833_ST_DISPLAYON (1 << 2) /* Bit 2: D10 - Display on */ -#define PCF8833_ST_PIXELSOFF (1 << 3) /* Bit 3: D11 - All pixels off */ -#define PCF8833_ST_PIXELSON (1 << 4) /* Bit 4: D12 - All pixels on */ -#define PCF8833_ST_INV (1 << 5) /* Bit 5: D13 - Display inversion */ -#define PCF8833_ST_VSCROLL (1 << 7) /* Bit 6: D15 - Vertical scroll mode */ - -/* Byte 4: All zero */ - -#endif /* __DRIVERS_LCD_PCF8833_H */
\ No newline at end of file diff --git a/nuttx/drivers/lcd/s1d15g10.h b/nuttx/drivers/lcd/s1d15g10.h deleted file mode 100644 index 9b5f7738f..000000000 --- a/nuttx/drivers/lcd/s1d15g10.h +++ /dev/null @@ -1,141 +0,0 @@ -/************************************************************************************** - * drivers/lcd/s1d15g10.h - * Definitions for the Epson S1D15G0 LCD controller - * - * Copyright (C) 2010 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt <gnutt@nuttx.org> - * - * References: S1D15G0D08B000, Seiko Epson Corportation, 2002. - * - * 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 written 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. - * - **************************************************************************************/ - -#ifndef __DRIVERS_LCD_S1D15G10_H -#define __DRIVERS_LCD_S1D15G10_H - -/************************************************************************************** - * Included Files - **************************************************************************************/ - -/************************************************************************************** - * Pre-processor Definitions - **************************************************************************************/ - -/* Epson S1D15G10 Command Set */ - -#define S1D15G10_DISON 0xaf /* Display on; Data: none */ -#define S1D15G10_DISOFF 0xae /* Display off; Data: none */ -#define S1D15G10_DISNOR 0xa6 /* Normal display; Data: none */ -#define S1D15G10_DISINV 0xa7 /* Inverse display; Data: none */ -#define S1D15G10_COMSCN 0xbb /* Common scan direction; Data: (1) common scan direction */ -#define S1D15G10_DISCTL 0xca /* Display control; Data: Data: (1) CL div, F1/2 pat, (2) duty, (3) FR inverse (4) dispersion */ -#define S1D15G10_SLPIN 0x95 /* Sleep in; Data: none */ -#define S1D15G10_SLPOUT 0x94 /* Sleep out; Data: none */ -#define S1D15G10_PASET 0x75 /* Page address set; Data: (1) start page, (2) end page */ -#define S1D15G10_CASET 0x15 /* Column address set; Data: (1) start addr, (2) end addr */ -#define S1D15G10_DATCTL 0xbc /* Data scan direction, etc.; Data: (1) inverse, scan dir (2) RGB, (3) gray-scale */ -#define S1D15G10_RGBSET8 0xce /* 256-color position set; Data: (1-8) red tones, (9-16) green tones, (17-20) blue tones */ -#define S1D15G10_RAMWR 0x5c /* Writing to memory; Data: (1) write data */ -#define S1D15G10_RAMRD 0x5d /* Reading from memory; Data: (1) read data */ -#define S1D15G10_PTLIN 0xa8 /* Partial display in; Data: (1) start addr, (2) end addr */ -#define S1D15G10_PTLOUT 0xa9 /* Partial display out; Data: none */ -#define S1D15G10_RMWIN 0xe0 /* Read and modify write; Data: none */ -#define S1D15G10_RMWOUT 0xee /* End; Data: none */ -#define S1D15G10_ASCSET 0xaa /* Area scroll set; Data: (1) top addr, (2) bottom addr, (3) Num blocks, (4) scroll mode */ -#define S1D15G10_SCSTART 0xab /* Scroll start set; Data: (1) start block addr */ -#define S1D15G10_OSCON 0xd1 /* Internal oscillation on; Data: none */ -#define S1D15G10_OSCOFF 0xd2 /* Internal oscillation off; Data: none */ -#define S1D15G10_PWRCTR 0x20 /* Power control; Data: (1) LCD drive power */ -#define S1D15G10_VOLCTR 0x81 /* Electronic volume control; Data: (1) volume value, (2) resistance ratio */ -#define S1D15G10_VOLUP 0xd6 /* Increment electronic control by 1; Data: none */ -#define S1D15G10_VOLDOWN 0xd7 /* Decrement electronic control by 1; Data: none */ -#define S1D15G10_TMPGRD 0x82 /* Temperature gradient set; Data: (1-14) temperature gradient */ -#define S1D15G10_EPCTIN 0xcd /* Control EEPROM; Data: (1) read/write */ -#define S1D15G10_EPCOUT 0xcc /* Cancel EEPROM control; Data: none */ -#define S1D15G10_EPMWR 0xfc /* Write into EEPROM; Data: none */ -#define S1D15G10_EPMRD 0xfd /* Read from EEPROM; Data: none */ -#define S1D15G10_EPSRRD1 0x7c /* Read register 1; Data: none */ -#define S1D15G10_EPSRRD2 0x7d /* Read regiser 2; Data: none */ -#define S1D15G10_NOP 0x25 /* NOP intruction (0x45?); Data: none */ -#define S1D15G10_STREAD 0x20 /* Status read; Data: none */ - -/* Display control (DISCTL) bit definitions */ - -#define DISCTL_PERIOD_SHIFT (0) /* P1: Bits 0-1, F1 and F2 drive-pattern switching period */ -#define DISCTL_PERIOD_MASK (3 << DISCTL_PERIOD_SHIFT) -# define DISCTL_PERIOD_8 (0 << DISCTL_PERIOD_SHIFT) -# define DISCTL_PERIOD_4 (1 << DISCTL_PERIOD_SHIFT) -# define DISCTL_PERIOD_16 (2 << DISCTL_PERIOD_SHIFT) -# define DISCTL_PERIOD_FLD (3 << DISCTL_PERIOD_SHIFT) -#define DISCTL_CLDIV_SHIFT (2) /* P1: Bits 2-4, Clock divider */ -#define DISCTL_CLDIV_MASK (7 << DISCTL_CLDIV_SHIFT) -# define DISCTL_CLDIV_2 (0 << DISCTL_CLDIV_SHIFT) -# define DISCTL_CLDIV_4 (1 << DISCTL_CLDIV_SHIFT) -# define DISCTL_CLDIV_8 (2 << DISCTL_CLDIV_SHIFT) -# define DISCTL_CLDIV_NONE (3 << DISCTL_CLDIV_SHIFT) - -/* Power control (PWRCTR) bit definitions */ - -#define PWCTR_REFVOLTAGE (1 << 0) /* P1: Bit 0, Turn on reference voltage generation circuit. */ -#define PWCTR_REGULATOR (1 << 1) /* P1: Bit 1, Turn on voltage regulator and circuit voltage follower. */ -#define PWCTR_BOOSTER2 (1 << 2) /* P1: Bit 2, Turn on secondary booster/step-down circuit. */ -#define PWCTR_BOOSTER1 (1 << 3) /* P1: Bit 3, Turn on primary booster circuit. */ -#define PWCTR_EXTR (1 << 4) /* P1: Bit 4, Use external resistance to adjust voltage. */ - -/* Data control (DATCTL) bit definitions */ - -#define DATCTL_PGADDR_INV (1 << 0) /* P1: Bit 0, Inverse display of the page address. */ -#define DATCTL_COLADDR_REV (1 << 1) /* P1: Bit 1, Reverse turn of column address. */ -#define DATCTL_ADDR_PGDIR (1 << 2) /* P1: Bit 2, Address-scan direction in page (vs column) direction. */ - -#define DATCTL_BGR (1 << 0) /* P2: Bit0, RGB->BGR */ - -#define DATCTL_8GRAY (1) /* P3: Bits 0-2 = 001, 8 gray-scale */ -#define DATCTL_16GRAY_A (2) /* P3: Bits 0-2 = 010, 16 gray-scale display type A */ -#define DATCTL_16GRAY_B (4) /* P3: Bits 0-2 = 100, 16 gray-scale display type B */ - -/* Status register bit definions (after reset or NOP) */ - -#define S1D15G10_SR_PARTIAL (1 << 0) /* Bit 0: Partial display */ -#define S1D15G10_SR_NORMAL (1 << 1) /* Bit 1: Normal (vs. inverse) display */ -#define S1D15G10_SR_EEPROM (1 << 2) /* Bit 2: EEPROM access */ -#define S1D15G10_SR_DISPON (1 << 3) /* Bit 3: Display on */ -#define S1D15G10_SR_COLSCAN (1 << 4) /* Bit 4: Column (vs. page) scan direction */ -#define S1D15G10_SR_RMW (1 << 5) /* Bit 5: Read modify write */ -#define S1D15G10_SR_SCROLL (3 << 6) /* Bits 6-7: Area scroll mode */ - -/* Status register bit definions (after EPSRRD1) */ - -#define S1D15G10_SR_VOLUME 0x3f /* Bits 0-5: Electronic volume control values */ - -/* Status register bit definions (after EPSRRD2) */ - -#define S1D15G10_SR_RRATIO 0x07 /* Bits 0-2: Built-in resistance ratio */ - -#endif /* __DRIVERS_LCD_S1D15G10_H */
\ No newline at end of file diff --git a/nuttx/drivers/lcd/sd1329.h b/nuttx/drivers/lcd/sd1329.h deleted file mode 100644 index 5d2ad4948..000000000 --- a/nuttx/drivers/lcd/sd1329.h +++ /dev/null @@ -1,527 +0,0 @@ -/**************************************************************************** - * drivers/lcd/sd1329.h - * - * Copyright (C) 2010 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt <gnutt@nuttx.org> - * - * 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 written 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. - * - ****************************************************************************/ - -#ifndef __DRIVERS_LCD_SD1329_H -#define __DRIVERS_LCD_SD1329_H - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include <nuttx/config.h> -#include <stdint.h> - -/**************************************************************************** - * Pre-Processor Definitions - ****************************************************************************/ - -/* SD1329 Commands **********************************************************/ -/* Set column Address. - * - * This triple byte command specifies column start address and end address of - * the display data RAM. This command also sets the column address pointer to - * column start address. This pointer is used to define the current read/write - * column address in graphic display data RAM. If horizontal address increment - * mode is enabled by command 0xa0, after finishing read/write one column data, - * it is incremented automatically to the next column address. Whenever the - * column address pointer finishes accessing the end column address, it is - * reset back to start column address and the row address is incremented to the - * next row. - * - * Byte 1: 0x15 - * Byte 2: A[5:0]: Start Address, range: 0x00-0x3f - * Byte 3: B[5:0]: End Address, range: 0x00-0x3f - */ - -#define SSD1329_SET_COLADDR 0x15 - -/* Set Row Address. - * - * This triple byte command specifies row start address and end address of the - * display data RAM. This command also sets the row address pointer to row - * start address. This pointer is used to define the current read/write row - * address in graphic display data RAM. If vertical address increment mode is - * enabled by command 0xa0, after finishing read/write one row data, it is - * incremented automatically to the next row address. Whenever the row address - * pointer finishes accessing the end row address, it is reset back to start - * row address. - * - * Byte 1: 0x75 - * Byte 2: A[6:0]: Start Address, range: 0x00-0x7f - * Byte 3: B[6:0]: End Address, range: 0x00-0x7f - */ - -#define SSD1329_SET_ROWADDR 0x75 - -/* Set Contract Current - * - * This double byte command is to set Contrast Setting of the display. The - * chip has 256 contrast steps from 0x00 to 0xff. The segment output current - * increases linearly with the increase of contrast step. - * - * Byte 1: 0x81 - * Byte 2: A[7:0]: Contrast Value, range: 0-255 - */ - -#define SSD1329_SET_CONTRAST 0x81 - -/* Set Second Pre-Charge Speed - * - * This command is used to set the speed of second pre-charge in phase 3. - * This speed can be doubled to achieve faster pre-charging through setting - * 0x82 A[0]. - * - * Byte 1: 0x82 - * Byte 2: A[7:1]: Second Pre-charge Speed - * A[0] = 1, Enable doubling the Second Pre-charge speed - */ - -#define SSD1329_PRECHRG2_SPEED 0x82 -# define SSD1329_PRECHRG2_DBL 0x01 - -/* Set Master Icon Control - * - * This double command is used to set the ON / OFF conditions of internal - * charge pump, icon circuits and overall icon status. - * - * Byte 1: 0x90 - * Byte 2: Icon control (OR of bits 0-1,4-5) - */ - -#define SSD1329_ICON_CONTROL 0x90 -# define SSD1329_ICON_NORMAL 0x00 /* A[1:0]1=00: Icon RESET to normal display */ -# define SSD1329_ICON_ALLON 0x01 /* A[1:0]1=01: Icon All ON */ -# define SSD1329_ICON_ALLOFF 0x02 /* A[1:0]=10: Icon All OFF */ -# define SSD1329_ICON_DISABLE 0x00 /* A[4]=0: Disable Icon display */ -# define SSD1329_ICON_ENABLE 0x10 /* A[4]=1: Enable Icon display */ -# define SSD1329_VICON_DISABLE 0x00 /* A[5]=0: Disable VICON charge pump circuit */ -# define SSD1329_VICON_ENABLE 0x20 /* A[5]=1: Enable VICON charge pump circuit */ - -/* Set Icon Current Range - * - * This double byte command is used to set one fix current range for all icons - * between the range of 0uA and 127.5uA. The uniformity improves as the icon - * current range increases. - * - * Byte 1: 0x91 - * Byte 2: A[7:0]: Max icon current: - * 00 = 0.0 uA - * 01 = 0.5 uA - * ... - * ff = 127.5 uA - */ - -#define SSD1329_ICON_CURRRNG 0x91 - -/* Set Individual Icon Current - * - * This multiple byte command is used to fine tune the current for each of the - * 64 icons. Command 0x92 followed by 64 single byte data. These 64 byte data - * have to be entered in order to make this command function. Below is the - * formula for calculating the icon current. - * - * Icon Current = Single byte value / 127 x Maximum icon current set with command 0x91 - * - * Byte 1: 0x92 - * Byte 2-65: An[6:0]: icon current for ICSn, range: 0x00-0x7f - * Icon Current of ICSn = An[6:0]/127) x max icon current - */ - -#define SSD1329_ICON_CURRENT 0x92 - -/* Set Individual Icon ON / OFF Register - * - * This double byte command is used to select one of the 64 icons and choose the - * ON, OFF or blinking condition of the selected icon. - * - * Byte 1: 0x93 - * Byte 2: A[5:0]: Select one of the 64 icons from ICS0 ~ ICS63 - * A[7:6]: OFF/ON/BLINK - */ - -#define SSD1329_ICON_SELECT 0x93 -# define SSD1329_ICON_OFF 0x00 -# define SSD1329_ICON_ON 0x40 -# define SSD1329_ICON_BLINK 0xc0 - -/* Set Icon ON / OFF Registers - * - * This double byte command is used to set the ON / OFF status of all 64 icons. - * - * Byte 1: 0x94 - * Byte 2: A[7:6]: OFF/ON/BLINK (Same as 0x93) - */ - -#define SSD1329_ICON_ALL 0x94 - -/* Set Icon Blinking Cycle - * - * This double byte command is used to set icon oscillator frequency and - * blinking cycle selected with above command 0x93. - * - * Byte 1: 0x95 - * Byte 2: - * - A[2:0]:Icon Blinking cycle - * - A[5:4]:Icon oscillation frequency - */ - -#define SSD1329_ICON_BLINKING 0x95 -# define SSD1329_ICON_BLINK_0p25S 0x00 /* 0.25 sec */ -# define SSD1329_ICON_BLINK_0p50S 0x01 /* 0.50 sec */ -# define SSD1329_ICON_BLINK_0p75S 0x02 /* 0.75 sec */ -# define SSD1329_ICON_BLINK_0p100S 0x03 /* 1.00 sec */ -# define SSD1329_ICON_BLINK_0p125S 0x04 /* 1.25 sec */ -# define SSD1329_ICON_BLINK_0p150S 0x05 /* 1.50 sec */ -# define SSD1329_ICON_BLINK_0p175S 0x06 /* 1.75 sec */ -# define SSD1329_ICON_BLINK_0p200S 0x07 /* 2.00 sec */ -# define SSD1329_ICON_BLINK_61KHZ 0x00 /* 61 KHz */ -# define SSD1329_ICON_BLINK_64KHZ 0x10 /* 64 KHz */ -# define SSD1329_ICON_BLINK_68KHZ 0x20 /* 68 KHz */ -# define SSD1329_ICON_BLINK_73KHZ 0x30 /* 73 KHz */ - -/* Set Icon Duty - * - * This double byte command is used to set the icon frame frequency and icon AC - * drive duty ratio. - * - * Byte 1: 0x96 - * Byte 2: - * - A[2:0]: AC Drive - * - A[7:4]: con frame frequency - */ - -#define SSD1329_ICON_ACDRIVE 0x96 -# define SSD1329_ICON_DUTY_DC 0x00 -# define SSD1329_ICON_DUTY_63_64 0x01 -# define SSD1329_ICON_DUTY_62_64 0x02 -# define SSD1329_ICON_DUTY_61_64 0x03 -# define SSD1329_ICON_DUTY_60_64 0x04 -# define SSD1329_ICON_DUTY_59_64 0x05 -# define SSD1329_ICON_DUTY_58_64 0x06 -# define SSD1329_ICON_DUTY_57_64 0x07 - -/* Set Re-map - * - * This double command has multiple configurations and each bit setting is - * described as follows: - * - * Column Address Remapping (A[0]) - * This bit is made for increase the flexibility layout of segment signals in - * OLED module with segment arranged from left to right (when A[0] is set to 0) - * or from right to left (when A[0] is set to 1). - * - * Nibble Remapping (A[1]) - * When A[1] is set to 1, the two nibbles of the data bus for RAM access are - * re-mapped, such that (D7, D6, D5, D4, D3, D2, D1, D0) acts like (D3, D2, D1, - * D0, D7, D6, D5, D4) If this feature works together with Column Address - * Re-map, it would produce an effect of flipping the outputs from SEG0-127 to - * SEG127-SEG0. - * - * Address increment mode (A[2]) - * When A[2] is set to 0, the driver is set as horizontal address incremen - * mode. After the display RAM is read/written, the column address pointer is - * increased automatically by 1. If the column address pointer reaches column - * end address, the column address pointer is reset to column start address and - * row address pointer is increased by 1. - * - * When A[2] is set to 1, the driver is set to vertical address increment mode. - * After the display RAM is read/written, the row address pointer is increased - * automatically by 1. If the row address pointer reaches the row end address, - * the row address pointer is reset to row start address and column address - * pointer is increased by 1. - * - * COM Remapping (A[4]) - * This bit defines the scanning direction of the common for flexible layout - * of common signals in OLED module either from up to down (when A[4] is set to - * 0) or from bottom to up (when A[4] is set to 1). - * - * Splitting of Odd / Even COM Signals (A[6]) - * This bit is made to match the COM layout connection on the panel. When A[6] - * is set to 0, no splitting odd / even of the COM signal is performed. When - * A[6] is set to 1, splitting odd / even of the COM signal is performed, - * output pin assignment sequence is shown as below (for 128MUX ratio): - * - * Byte 1: 0xa0 - * Byte 2: A[7:0] - */ - -#define SSD1329_GDDRAM_REMAP 0xa0 -# define SSD1329_COLADDR_REMAP 0x01 /* A[0]: Enable column re-map */ -# define SSD1329_NIBBLE_REMAP 0x02 /* A[1]: Enable nibble re-map */ -# define SSD1329_VADDR_INCR 0x04 /* A[1]: Enable vertical address increment */ -# define SSD1329_COM_REMAP 0x10 /* A[4]: Enable COM re-map */ -# define SSD1329_COM_SPLIT 0x40 /* A[6]: Enable COM slip even/odd */ - -/* Set Display Start Line - * - * This double byte command is to set Display Start Line register for - * determining the starting address of display RAM to be displayed by selecting - * a value from 0 to 127. - * - * Byte 1: 0xa1 - * Byte 2: A[6:0]: Vertical scroll by setting the starting address of - * display RAM from 0-127 - */ - -#define SSD1329_VERT_START 0xa1 - -/* Set Display Offset - * - * This double byte command specifies the mapping of display start line (it is - * assumed that COM0 is the display start line, display start line register - * equals to 0) to one of COM0-COM127. - * - * Byte 1: 0xa2 - * Byte 2: A[6:0]: Set vertical offset by COM from 0-127 - */ - -#define SSD1329_VERT_OFFSET 0xa2 - -/* Set Display Mode - Normal, all on, all off, inverse - * - * These are single byte commands and are used to set display status to Normal - * Display, Entire Display ON, Entire Display OFF or Inverse Display. - * - * Normal Display (0xa4) - * Reset the “Entire Display ON, Entire Display OFF or Inverse Display” effects - * and turn the data to ON at the corresponding gray level. - * - * Set Entire Display ON (0xa5) - * Force the entire display to be at gray scale level GS15, regardless of the - * contents of the display data RAM. - * - * Set Entire Display OFF (0xa6) - * Force the entire display to be at gray scale level GS0, regardless of the - * contents of the display data RAM. - * - * Inverse Display (0xa7) - * The gray scale level of display data are swapped such that “GS0” <-> “GS15”, - * “GS1” <-> “GS14”, etc. - * - * Byte 1: Display mode command - */ - -#define SSD1329_DISP_NORMAL 0xa4 -#define SSD1329_DISP_OFF 0xa5 -#define SSD1329_DISP_ON 0xa6 -#define SSD1329_DISP_INVERT 0xa7 - -/* Set MUX Ratio - * - * This double byte command sets multiplex ratio (MUX ratio) from 16MUX to - * 128MUX. In POR, multiplex ratio is 128MUX. - * - * Byte 1: 0xa8 - * Byte 2: A[6:0] 15-127 representing 16-128 MUX - */ - -#define SSD1329_MUX_RATIO 0xa8 - -/* Set Sleep mode ON / OFF - * - * These single byte commands are used to turn the matrix display on the OLED - * panel display either ON or OFF. When the sleep mode is set to ON (0xae), the - * display is OFF, the segment and common output are in high impedance state - * and circuits will be turned OFF. When the sleep mode is set to OFF (0xaf), - * the display is ON. - * - * Byte 1: sleep mode command - */ - -#define SSD1329_SLEEP_ON 0xae -#define SSD1329_SLEEP_OFF 0xaf - -/* Set Phase Length - * - * In the second byte of this double command, lower nibble and higher nibble is - * defined separately. The lower nibble adjusts the phase length of Reset (phase - * 1). The higher nibble is used to select the phase length of first pre-charge - * phase (phase 2). The phase length is ranged from 1 to 16 DCLK's. RESET for - * A[3:0] is set to 3 which means 4 DCLK’s selected for Reset phase. POR for - * A[7:4] is set to 5 which means 6 DCLK’s is selected for first pre-charge - * phase. Please refer to Table 9-1 for detail breakdown levels of each step. - * - * Byte 1: 0xb1 - * Byte 2: A[3:0]: Phase 1 period of 1~16 DCLK’s - * A[7:4]: Phase 2 period of 1~16 DCLK’s - */ - -#define SSD1329_PHASE_LENGTH 0xb1 - -/* Set Frame Frequency - * - * This double byte command is used to set the number of DCLK’s per row between - * the range of 0x14 and 0x7f. Then the Frame frequency of the matrix display - * is equal to DCLK frequency / A[6:0]. - * - * Byte 1: 0xb2 - * Byte 2: A[6:0]:Total number of DCLK’s per row. Ranging from - * 0x14 to 0x4e DCLK’s. frame Frequency = DCLK freq /A[6:0]. - */ - -#define SSD1329_FRAME_FREQ 0xb2 - -/* Set Front Clock Divider / Oscillator Frequency - * - * This double command is used to set the frequency of the internal display - * clocks, DCLK's. It is defined by dividing the oscillator frequency by the - * divide ratio (Value from 1 to 16). Frame frequency is determined by divide - * ratio, number of display clocks per row, MUX ratio and oscillator frequency. - * The lower nibble of the second byte is used to select the oscillator - * frequency. Please refer to Table 9-1 for detail breakdown levels of each - * step. - * - * Byte 1: 0xb3 - * Byte 2: A[3:0]: Define divide ratio (D) of display clock (DCLK) - * Divide ratio=A[3:0]+1 - * A[7:4] : Set the Oscillator Frequency, FOSC. Range:0-15 - */ - -#define SSD1329_DCLK_DIV 0xb3 - -/* Set Default Gray Scale Table - * - * This single byte command is used to set the gray scale table to initial - * default setting. - * - * Byte 1: 0xb7 - */ - -#define SSD1329_GSCALE_TABLE 0xb7 - -/* Look Up Table for Gray Scale Pulse width - * - * This command is used to set each individual gray scale level for the display. - * Except gray scale level GS0 that has no pre-charge and current drive, each - * gray scale level is programmed in the length of current drive stage pulse - * width with unit of DCLK. The longer the length of the pulse width, the - * brighter the OLED pixel when it’s turned ON. - * - * The setting of gray scale table entry can perform gamma correction on OLED - * panel display. Normally, it is desired that the brightness response of the - * panel is linearly proportional to the image data value in display data RAM. - * However, the OLED panel is somehow responded in non-linear way. Appropriate - * gray scale table setting like example below can compensate this effect. - * - * Byte 1: 0xb8 - * Bytes 2-16: An[5:0], value for GSn level Pulse width - */ - -#define SSD1329_GSCALE_LOOKUP 0xb8 - -/* Set Second Pre-charge Period - * - * This double byte command is used to set the phase 3 second pre-charge period. - * The period of phase 3 can be programmed by command 0xbb and it is ranged from - * 0 to 15 DCLK's. - * - * Byte 1: 0xbb - * Byte 2: 0-15 DCLKs - */ - -#define SSD1329_PRECHRG2_PERIOD 0xbb - -/* Set First Precharge voltage, VP - * - * This double byte command is used to set phase 2 first pre-charge voltage - * level. It can be programmed to set the first pre-charge voltage reference to - * VCC or VCOMH. - * - * Byte 1: 0xbc - * Byte 2: A[5] == 0, Pre-charge voltage is (0.30 + A[4:0]) * Vcc - * A{5] == 1, 1.00 x VCC or connect to VCOMH if VCC > VCOMH - */ - -#define SSD1329_PRECHRG1_VOLT 0xbc - -/* Set VCOMH - * - * This double byte command sets the high voltage level of common pins, VCOMH. - * The level of VCOMH is programmed with reference to VCC. - * - * Byte 1: 0xbe - * Byte 2: (0.51 + A[5:0]) * Vcc - */ - -#define SSD1329_COM_HIGH 0xbe - -/* NOOP - * - * This is a no operation command. - * - * Byte 1: 0xe3 - */ - -#define SSD1329_NOOP 0xe3 - -/* Set Command Lock - * - * This command is used to lock the MCU from accepting any command. - * - * Byte 1: 0xfd - * Byte 2: 0x12 | A[2] - * A[2] == 1, Enable locking the MCU from entering command - */ - -#define SSD1329_CMD_LOCK 0xfd -# define SSD1329_LOCK_ON 0x13 -# define SSD1329_LOCK_OFF 0x12 - -/* SD1329 Status ************************************************************/ - -#define SDD1329_STATUS_ON 0x00 /* D[6]=0: indicates the display is ON */ -#define SDD1329_STATUS_OFF 0x40 /* D[6]=1: indicates the display is OFF */ - -/**************************************************************************** - * Public Types - ****************************************************************************/ - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -#undef EXTERN -#if defined(__cplusplus) -#define EXTERN extern "C" -extern "C" { -#else -#define EXTERN extern -#endif - -#undef EXTERN -#if defined(__cplusplus) -} -#endif -#endif /* __DRIVERS_LCD_SD1329_H */ diff --git a/nuttx/drivers/lcd/skeleton.c b/nuttx/drivers/lcd/skeleton.c deleted file mode 100644 index 83aa92018..000000000 --- a/nuttx/drivers/lcd/skeleton.c +++ /dev/null @@ -1,401 +0,0 @@ -/************************************************************************************** - * drivers/lcd/skeleton.c - * - * Copyright (C) 2011 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt <gnutt@nuttx.org> - * - * 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 written 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. - * - **************************************************************************************/ - -/************************************************************************************** - * Included Files - **************************************************************************************/ - -#include <nuttx/config.h> - -#include <sys/types.h> -#include <stdint.h> -#include <stdbool.h> -#include <string.h> -#include <errno.h> -#include <debug.h> - -#include <nuttx/arch.h> -#include <nuttx/spi.h> -#include <nuttx/lcd/lcd.h> - -#include "up_arch.h" - -/************************************************************************************** - * Pre-processor Definitions - **************************************************************************************/ - -/* Configuration **********************************************************************/ -/* Verify that all configuration requirements have been met */ - -/* Debug ******************************************************************************/ -/* Define the following to enable register-level debug output */ - -#undef CONFIG_LCD_SKELDEBUG - -/* Verbose debug must also be enabled */ - -#ifndef CONFIG_DEBUG -# undef CONFIG_DEBUG_VERBOSE -# undef CONFIG_DEBUG_GRAPHICS -#endif - -#ifndef CONFIG_DEBUG_VERBOSE -# undef CONFIG_LCD_SKELDEBUG -#endif - -/* Color Properties *******************************************************************/ - -/* Display Resolution */ - -#define SKEL_XRES 320 -#define SKEL_YRES 240 - -/* Color depth and format */ - -#define SKEL_BPP 16 -#define SKEL_COLORFMT FB_FMT_RGB16_565 - -/* Debug ******************************************************************************/ - -#ifdef CONFIG_LCD_SKELDEBUG -# define skeldbg(format, arg...) vdbg(format, ##arg) -#else -# define skeldbg(x...) -#endif - -/************************************************************************************** - * Private Type Definition - **************************************************************************************/ - -/* This structure describes the state of this driver */ - -struct skel_dev_s -{ - /* Publically visible device structure */ - - struct lcd_dev_s dev; - - /* Private LCD-specific information follows */ -}; - -/************************************************************************************** - * Private Function Protototypes - **************************************************************************************/ - -/* LCD Data Transfer Methods */ - -static int skel_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer, - size_t npixels); -static int skel_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer, - size_t npixels); - -/* LCD Configuration */ - -static int skel_getvideoinfo(FAR struct lcd_dev_s *dev, - FAR struct fb_videoinfo_s *vinfo); -static int skel_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planeno, - FAR struct lcd_planeinfo_s *pinfo); - -/* LCD RGB Mapping */ - -#ifdef CONFIG_FB_CMAP -# error "RGB color mapping not supported by this driver" -#endif - -/* Cursor Controls */ - -#ifdef CONFIG_FB_HWCURSOR -# error "Cursor control not supported by this driver" -#endif - -/* LCD Specific Controls */ - -static int skel_getpower(struct lcd_dev_s *dev); -static int skel_setpower(struct lcd_dev_s *dev, int power); -static int skel_getcontrast(struct lcd_dev_s *dev); -static int skel_setcontrast(struct lcd_dev_s *dev, unsigned int contrast); - -/************************************************************************************** - * Private Data - **************************************************************************************/ - -/* This is working memory allocated by the LCD driver for each LCD device - * and for each color plane. This memory will hold one raster line of data. - * The size of the allocated run buffer must therefore be at least - * (bpp * xres / 8). Actual alignment of the buffer must conform to the - * bitwidth of the underlying pixel type. - * - * If there are multiple planes, they may share the same working buffer - * because different planes will not be operate on concurrently. However, - * if there are multiple LCD devices, they must each have unique run buffers. - */ - -static uint16_t g_runbuffer[SKEL_XRES]; - -/* This structure describes the overall LCD video controller */ - -static const struct fb_videoinfo_s g_videoinfo = -{ - .fmt = SKEL_COLORFMT, /* Color format: RGB16-565: RRRR RGGG GGGB BBBB */ - .xres = SKEL_XRES, /* Horizontal resolution in pixel columns */ - .yres = SKEL_YRES, /* Vertical resolution in pixel rows */ - .nplanes = 1, /* Number of color planes supported */ -}; - -/* This is the standard, NuttX Plane information object */ - -static const struct lcd_planeinfo_s g_planeinfo = -{ - .putrun = skel_putrun, /* Put a run into LCD memory */ - .getrun = skel_getrun, /* Get a run from LCD memory */ - .buffer = (uint8_t*)g_runbuffer, /* Run scratch buffer */ - .bpp = SKEL_BPP, /* Bits-per-pixel */ -}; - -/* This is the standard, NuttX LCD driver object */ - -static struct skel_dev_s g_lcddev = -{ - .dev = - { - /* LCD Configuration */ - - .getvideoinfo = skel_getvideoinfo, - .getplaneinfo = skel_getplaneinfo, - - /* LCD RGB Mapping -- Not supported */ - /* Cursor Controls -- Not supported */ - - /* LCD Specific Controls */ - - .getpower = skel_getpower, - .setpower = skel_setpower, - .getcontrast = skel_getcontrast, - .setcontrast = skel_setcontrast, - }, -}; - -/************************************************************************************** - * Private Functions - **************************************************************************************/ - -/************************************************************************************** - * Name: skel_putrun - * - * Description: - * This method can be used to write a partial raster line to the LCD: - * - * row - Starting row to write to (range: 0 <= row < yres) - * col - Starting column to write to (range: 0 <= col <= xres-npixels) - * buffer - The buffer containing the run to be written to the LCD - * npixels - The number of pixels to write to the LCD - * (range: 0 < npixels <= xres-col) - * - **************************************************************************************/ - -static int skel_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer, - size_t npixels) -{ - /* Buffer must be provided and aligned to a 16-bit address boundary */ - - gvdbg("row: %d col: %d npixels: %d\n", row, col, npixels); - DEBUGASSERT(buffer && ((uintptr_t)buffer & 1) == 0); - - /* Set up to write the run. */ - - /* Write the run to GRAM. */ -#warning "Missing logic" - return OK; -} - -/************************************************************************************** - * Name: skel_getrun - * - * Description: - * This method can be used to read a partial raster line from the LCD: - * - * 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) - * - **************************************************************************************/ - -static int skel_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer, - size_t npixels) -{ - /* Buffer must be provided and aligned to a 16-bit address boundary */ - - gvdbg("row: %d col: %d npixels: %d\n", row, col, npixels); - DEBUGASSERT(buffer && ((uintptr_t)buffer & 1) == 0); - -#warning "Missing logic" - return -ENOSYS; -} - -/************************************************************************************** - * Name: skel_getvideoinfo - * - * Description: - * Get information about the LCD video controller configuration. - * - **************************************************************************************/ - -static int skel_getvideoinfo(FAR struct lcd_dev_s *dev, - FAR struct fb_videoinfo_s *vinfo) -{ - DEBUGASSERT(dev && vinfo); - gvdbg("fmt: %d xres: %d yres: %d nplanes: %d\n", - g_videoinfo.fmt, g_videoinfo.xres, g_videoinfo.yres, g_videoinfo.nplanes); - memcpy(vinfo, &g_videoinfo, sizeof(struct fb_videoinfo_s)); - return OK; -} - -/************************************************************************************** - * Name: skel_getplaneinfo - * - * Description: - * Get information about the configuration of each LCD color plane. - * - **************************************************************************************/ - -static int skel_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planeno, - FAR struct lcd_planeinfo_s *pinfo) -{ - DEBUGASSERT(dev && pinfo && planeno == 0); - gvdbg("planeno: %d bpp: %d\n", planeno, g_planeinfo.bpp); - memcpy(pinfo, &g_planeinfo, sizeof(struct lcd_planeinfo_s)); - return OK; -} - -/************************************************************************************** - * Name: skel_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. - * - **************************************************************************************/ - -static int skel_getpower(struct lcd_dev_s *dev) -{ - struct skel_dev_s *priv = (struct skel_dev_s *)dev; - gvdbg("power: %d\n", 0); -#warning "Missing logic" - return 0; -} - -/************************************************************************************** - * Name: skel_setpower - * - * Description: - * Enable/disable LCD panel power (0: full off - CONFIG_LCD_MAXPOWER: full on). On - * backlit LCDs, this setting may correspond to the backlight setting. - * - **************************************************************************************/ - -static int skel_setpower(struct lcd_dev_s *dev, int power) -{ - struct skel_dev_s *priv = (struct skel_dev_s *)dev; - - gvdbg("power: %d\n", power); - DEBUGASSERT(power <= CONFIG_LCD_MAXPOWER); - - /* Set new power level */ -#warning "Missing logic" - - return OK; -} - -/************************************************************************************** - * Name: skel_getcontrast - * - * Description: - * Get the current contrast setting (0-CONFIG_LCD_MAXCONTRAST). - * - **************************************************************************************/ - -static int skel_getcontrast(struct lcd_dev_s *dev) -{ - gvdbg("Not implemented\n"); -#warning "Missing logic" - return -ENOSYS; -} - -/************************************************************************************** - * Name: skel_setcontrast - * - * Description: - * Set LCD panel contrast (0-CONFIG_LCD_MAXCONTRAST). - * - **************************************************************************************/ - -static int skel_setcontrast(struct lcd_dev_s *dev, unsigned int contrast) -{ - gvdbg("contrast: %d\n", contrast); -#warning "Missing logic" - return -ENOSYS; -} - -/************************************************************************************** - * Public Functions - **************************************************************************************/ - -/************************************************************************************** - * Name: up_oledinitialize - * - * Description: - * Initialize the LCD 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). - * - **************************************************************************************/ - -FAR struct lcd_dev_s *up_oledinitialize(FAR struct spi_dev_s *spi) -{ - gvdbg("Initializing\n"); - - /* Configure GPIO pins */ -#warning "Missing logic" - - /* Enable clocking */ -#warning "Missing logic" - - /* Configure and enable LCD */ - #warning "Missing logic" - - return &g_lcddev.dev; -} diff --git a/nuttx/drivers/lcd/ssd1289.c b/nuttx/drivers/lcd/ssd1289.c deleted file mode 100644 index d78688be5..000000000 --- a/nuttx/drivers/lcd/ssd1289.c +++ /dev/null @@ -1,1380 +0,0 @@ -/************************************************************************************** - * drivers/lcd/ssd1289.c - * - * Generic LCD driver for LCDs based on the Solomon Systech SSD1289 LCD controller. - * Think of this as a template for an LCD driver that you will proably ahve to - * customize for any particular LCD hardware. - * - * Copyright (C) 2012 Gregory Nutt. All rights reserved. - * Authors: Gregory Nutt <gnutt@nuttx.org> - * - * References: SSD1289, Rev 1.3, Apr 2007, Solomon Systech Limited - * - * 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 written 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. - * - **************************************************************************************/ - -/************************************************************************************** - * Included Files - **************************************************************************************/ - -#include <nuttx/config.h> - -#include <sys/types.h> -#include <stdint.h> -#include <stdbool.h> -#include <string.h> -#include <errno.h> -#include <debug.h> - -#include <nuttx/arch.h> -#include <nuttx/spi.h> -#include <nuttx/lcd/lcd.h> -#include <nuttx/lcd/ssd1289.h> - -#include "ssd1289.h" - -#ifdef CONFIG_LCD_SSD1289 - -/************************************************************************************** - * Pre-processor Definitions - **************************************************************************************/ -/* Configuration **********************************************************************/ - -/* Check contrast selection */ - -#if !defined(CONFIG_LCD_MAXCONTRAST) -# define CONFIG_LCD_MAXCONTRAST 1 -#endif - -/* Check power setting */ - -#if !defined(CONFIG_LCD_MAXPOWER) || CONFIG_LCD_MAXPOWER < 1 -# define CONFIG_LCD_MAXPOWER 1 -#endif - -#if CONFIG_LCD_MAXPOWER > 255 -# error "CONFIG_LCD_MAXPOWER must be less than 256 to fit in uint8_t" -#endif - -/* Check orientation */ - -#if defined(CONFIG_LCD_PORTRAIT) -# if defined(CONFIG_LCD_LANDSCAPE) || defined(CONFIG_LCD_RLANDSCAPE) || defined(CONFIG_LCD_RPORTRAIT) -# error "Cannot define both portrait and any other orientations" -# endif -#elif defined(CONFIG_LCD_RPORTRAIT) -# if defined(CONFIG_LCD_LANDSCAPE) || defined(CONFIG_LCD_RLANDSCAPE) -# error "Cannot define both rportrait and any other orientations" -# endif -#elif defined(CONFIG_LCD_LANDSCAPE) -# ifdef CONFIG_LCD_RLANDSCAPE -# error "Cannot define both landscape and any other orientations" -# endif -#elif !defined(CONFIG_LCD_RLANDSCAPE) -# define CONFIG_LCD_LANDSCAPE 1 -#endif - -/* Define CONFIG_DEBUG_LCD to enable detailed LCD debug output. Verbose debug must - * also be enabled. - */ - -#ifndef CONFIG_DEBUG -# undef CONFIG_DEBUG_VERBOSE -# undef CONFIG_DEBUG_GRAPHICS -# undef CONFIG_DEBUG_LCD -#endif - -#ifndef CONFIG_DEBUG_VERBOSE -# undef CONFIG_DEBUG_LCD -#endif - -/* Display/Color Properties ***********************************************************/ -/* Display Resolution */ - -#if defined(CONFIG_LCD_LANDSCAPE) || defined(CONFIG_LCD_RLANDSCAPE) -# define SSD1289_XRES 320 -# define SSD1289_YRES 240 -#else -# define SSD1289_XRES 240 -# define SSD1289_YRES 320 -#endif - -/* Color depth and format */ - -#define SSD1289_BPP 16 -#define SSD1289_COLORFMT FB_FMT_RGB16_565 - -/* LCD Profiles ***********************************************************************/ -/* Many details of the controller initialization must, unfortunately, vary from LCD to - * LCD. I have looked at the spec and at three different drivers for LCDs that have - * SSD1289 controllers. I have tried to summarize these differences as "LCD profiles" - * - * Most of the differences between LCDs are nothing more than a few minor bit - * settings. The most significant difference betwen LCD drivers in is the - * manner in which the LCD is powered up and in how the power controls are set. - * My suggestion is that if you have working LCD initialization code, you should - * simply replace the code in ssd1289_hwinitialize with your working code. - */ - -#if defined (CONFIG_SSD1289_PROFILE2) -# undef SSD1289_USE_SIMPLE_INIT - - /* PWRCTRL1: AP=smalll-to-medium, DC=Flinex24, BT=+5/-4, DCT=Flinex24 */ - -# define PWRCTRL1_SETTING \ - (SSD1289_PWRCTRL1_AP_SMMED | SSD1289_PWRCTRL1_DC_FLINEx24 | \ - SSD1289_PWRCTRL1_BT_p5m4 | SSD1289_PWRCTRL1_DCT_FLINEx24) - - /* PWRCTRL2: 5.1v */ - -# define PWRCTRL2_SETTING SSD1289_PWRCTRL2_VRC_5p1V - - /* PWRCTRL3: x 2.165 - * NOTE: Many drivers have bit 8 set which is not defined in the SSD1289 spec. - */ - -# define PWRCTRL3_SETTING SSD1289_PWRCTRL3_VRH_x2p165 - - /* PWRCTRL4: VDV=9 + VCOMG */ - -# define PWRCTRL4_SETTING (SSD1289_PWRCTRL4_VDV(9) | SSD1289_PWRCTRL4_VCOMG) - - /* PWRCTRL5: VCM=56 + NOTP */ - -# define PWRCTRL5_SETTING (SSD1289_PWRCTRL5_VCM(56) | SSD1289_PWRCTRL5_NOTP) - -#elif defined (CONFIG_SSD1289_PROFILE3) -# undef SSD1289_USE_SIMPLE_INIT - - /* PWRCTRL1: AP=smalll-to-medium, DC=Flinex24, BT=+5/-4, DCT=Flinex24 */ - -# define PWRCTRL1_SETTING \ - (SSD1289_PWRCTRL1_AP_SMMED | SSD1289_PWRCTRL1_DC_FLINEx24 | \ - SSD1289_PWRCTRL1_BT_p5m4 | SSD1289_PWRCTRL1_DCT_FLINEx24) - - /* PWRCTRL2: 5.1v */ - -# define PWRCTRL2_SETTING SSD1289_PWRCTRL2_VRC_5p1V - - /* PWRCTRL3: x 2.165 - * NOTE: Many drivers have bit 8 set which is not defined in the SSD1289 spec. - */ - -# define PWRCTRL3_SETTING SSD1289_PWRCTRL3_VRH_x2p165 - - /* PWRCTRL4: VDV=9 + VCOMG */ - -# define PWRCTRL4_SETTING (SSD1289_PWRCTRL4_VDV(9) | SSD1289_PWRCTRL4_VCOMG) - - /* PWRCTRL5: VCM=56 + NOTP */ - -# define PWRCTRL5_SETTING (SSD1289_PWRCTRL5_VCM(56) | SSD1289_PWRCTRL5_NOTP) - -#else /* if defined (CONFIG_SSD1289_PROFILE1) */ -# undef SSD1289_USE_SIMPLE_INIT -# define SSD1289_USE_SIMPLE_INIT 1 - - /* PWRCTRL1: AP=medium-to-large, DC=Fosc/4, BT=+5/-4, DCT=Fosc/4 */ - -# define PWRCTRL1_SETTING \ - (SSD1289_PWRCTRL1_AP_MEDLG | SSD1289_PWRCTRL1_DC_FOSd4 | \ - SSD1289_PWRCTRL1_BT_p5m4 | SSD1289_PWRCTRL1_DCT_FOSd4) - - /* PWRCTRL2: 5.3v */ - -# define PWRCTRL2_SETTING SSD1289_PWRCTRL2_VRC_5p3V - - /* PWRCTRL3: x 2.570 - * NOTE: Many drivers have bit 8 set which is not defined in the SSD1289 spec. - */ - -# define PWRCTRL3_SETTING SSD1289_PWRCTRL3_VRH_x2p570 - - /* PWRCTRL4: VDV=12 + VCOMG */ - -# define PWRCTRL4_SETTING (SSD1289_PWRCTRL4_VDV(12) | SSD1289_PWRCTRL4_VCOMG) - - /* PWRCTRL5: VCM=60 + NOTP */ - -# define PWRCTRL5_SETTING (SSD1289_PWRCTRL5_VCM(60) | SSD1289_PWRCTRL5_NOTP) - -#endif - -/* Debug ******************************************************************************/ - -#ifdef CONFIG_DEBUG_LCD -# define lcddbg dbg -# define lcdvdbg vdbg -#else -# define lcddbg(x...) -# define lcdvdbg(x...) -#endif - -/************************************************************************************** - * Private Type Definition - **************************************************************************************/ - -/* This structure describes the state of this driver */ - -struct ssd1289_dev_s -{ - /* Publically visible device structure */ - - struct lcd_dev_s dev; - - /* Private LCD-specific information follows */ - - FAR struct ssd1289_lcd_s *lcd; /* The contained platform-specific, LCD interface */ - uint8_t power; /* Current power setting */ - - /* These fields simplify and reduce debug output */ - -#ifdef CONFIG_DEBUG_LCD - bool put; /* Last raster operation was a putrun */ - fb_coord_t firstrow; /* First row of the run */ - fb_coord_t lastrow; /* Last row of the run */ - fb_coord_t col; /* Column of the run */ - size_t npixels; /* Length of the run */ -#endif - - /* This is working memory allocated by the LCD driver for each LCD device - * and for each color plane. This memory will hold one raster line of data. - * The size of the allocated run buffer must therefore be at least - * (bpp * xres / 8). Actual alignment of the buffer must conform to the - * bitwidth of the underlying pixel type. - * - * If there are multiple planes, they may share the same working buffer - * because different planes will not be operate on concurrently. However, - * if there are multiple LCD devices, they must each have unique run buffers. - */ - - uint16_t runbuffer[SSD1289_XRES]; -}; - -/************************************************************************************** - * Private Function Protototypes - **************************************************************************************/ -/* Low Level LCD access */ - -static void ssd1289_putreg(FAR struct ssd1289_lcd_s *lcd, uint8_t regaddr, - uint16_t regval); -#ifndef CONFIG_LCD_NOGETRUN -static uint16_t ssd1289_readreg(FAR struct ssd1289_lcd_s *lcd, uint8_t regaddr); -#endif -static inline void ssd1289_gramwrite(FAR struct ssd1289_lcd_s *lcd, uint16_t rgbcolor); -#ifndef CONFIG_LCD_NOGETRUN -static inline void ssd1289_readsetup(FAR struct ssd1289_lcd_s *lcd, FAR uint16_t *accum); -static inline uint16_t ssd1289_gramread(FAR struct ssd1289_lcd_s *lcd, FAR uint16_t *accum); -#endif -static void ssd1289_setcursor(FAR struct ssd1289_lcd_s *lcd, uint16_t column, - uint16_t row); - -/* LCD Data Transfer Methods */ - -#if 0 /* Sometimes useful */ -static void ssd1289_dumprun(FAR const char *msg, FAR uint16_t *run, size_t npixels); -#else -# define ssd1289_dumprun(m,r,n) -#endif - -#ifdef CONFIG_DEBUG_LCD -static void ssd1289_showrun(FAR struct ssd1289_dev_s *priv, fb_coord_t row, - fb_coord_t col, size_t npixels, bool put); -#else -# define ssd1289_showrun(p,r,c,n,b) -#endif - -static int ssd1289_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer, - size_t npixels); -static int ssd1289_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer, - size_t npixels); - -/* LCD Configuration */ - -static int ssd1289_getvideoinfo(FAR struct lcd_dev_s *dev, - FAR struct fb_videoinfo_s *vinfo); -static int ssd1289_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planeno, - FAR struct lcd_planeinfo_s *pinfo); - -/* LCD RGB Mapping */ - -#ifdef CONFIG_FB_CMAP -# error "RGB color mapping not supported by this driver" -#endif - -/* Cursor Controls */ - -#ifdef CONFIG_FB_HWCURSOR -# error "Cursor control not supported by this driver" -#endif - -/* LCD Specific Controls */ - -static int ssd1289_getpower(FAR struct lcd_dev_s *dev); -static int ssd1289_setpower(FAR struct lcd_dev_s *dev, int power); -static int ssd1289_getcontrast(FAR struct lcd_dev_s *dev); -static int ssd1289_setcontrast(FAR struct lcd_dev_s *dev, unsigned int contrast); - -/* Initialization */ - -static inline int ssd1289_hwinitialize(FAR struct ssd1289_dev_s *priv); - -/************************************************************************************** - * Private Data - **************************************************************************************/ - -/* This driver can support only a signal SSD1289 device. This is due to an - * unfortunate decision made whent he getrun and putrun methods were designed. The - * following is the single SSD1289 driver state instance: - */ - -static struct ssd1289_dev_s g_lcddev; - -/************************************************************************************** - * Private Functions - **************************************************************************************/ - -/************************************************************************************** - * Name: ssd1289_putreg(lcd, - * - * Description: - * Write to an LCD register - * - **************************************************************************************/ - -static void ssd1289_putreg(FAR struct ssd1289_lcd_s *lcd, uint8_t regaddr, uint16_t regval) -{ - /* Set the index register to the register address and write the register contents */ - - lcd->index(lcd, regaddr); - lcd->write(lcd, regval); -} - -/************************************************************************************** - * Name: ssd1289_readreg - * - * Description: - * Read from an LCD register - * - **************************************************************************************/ - -#ifndef CONFIG_LCD_NOGETRUN -static uint16_t ssd1289_readreg(FAR struct ssd1289_lcd_s *lcd, uint8_t regaddr) -{ - /* Set the index register to the register address and read the register contents */ - - lcd->index(lcd, regaddr); - return lcd->read(lcd); -} -#endif - -/************************************************************************************** - * Name: ssd1289_gramselect - * - * Description: - * Setup to read or write multiple pixels to the GRAM memory - * - **************************************************************************************/ - -static inline void ssd1289_gramselect(FAR struct ssd1289_lcd_s *lcd) -{ - lcd->index(lcd, SSD1289_DATA); -} - -/************************************************************************************** - * Name: ssd1289_gramwrite - * - * Description: - * Setup to read or write multiple pixels to the GRAM memory - * - **************************************************************************************/ - -static inline void ssd1289_gramwrite(FAR struct ssd1289_lcd_s *lcd, uint16_t data) -{ - lcd->write(lcd, data); -} - -/************************************************************************************** - * Name: ssd1289_readsetup - * - * Description: - * Prime the operation by reading one pixel from the GRAM memory if necessary for - * this LCD type. When reading 16-bit gram data, there may be some shifts in the - * returned data: - * - * - ILI932x: Discard first dummy read; no shift in the return data - * - **************************************************************************************/ - -#ifndef CONFIG_LCD_NOGETRUN -static inline void ssd1289_readsetup(FAR struct ssd1289_lcd_s *lcd, FAR uint16_t *accum) -{ - /* Read-ahead one pixel */ - - *accum = lcd->read(lcd); -} -#endif - -/************************************************************************************** - * Name: ssd1289_gramread - * - * Description: - * Read one correctly aligned pixel from the GRAM memory. Possibly shifting the - * data and possibly swapping red and green components. - * - * - ILI932x: Unknown -- assuming colors are in the color order - * - **************************************************************************************/ - -#ifndef CONFIG_LCD_NOGETRUN -static inline uint16_t ssd1289_gramread(FAR struct ssd1289_lcd_s *lcd, FAR uint16_t *accum) -{ - /* Read the value (GRAM register already selected) */ - - return lcd->read(lcd); -} -#endif - -/************************************************************************************** - * Name: ssd1289_setcursor - * - * Description: - * Set the cursor position. In landscape mode, the "column" is actually the physical - * Y position and the "row" is the physical X position. - * - **************************************************************************************/ - -static void ssd1289_setcursor(FAR struct ssd1289_lcd_s *lcd, uint16_t column, uint16_t row) -{ -#if defined(CONFIG_LCD_PORTRAIT) || defined(CONFIG_LCD_RPORTRAIT) - ssd1289_putreg(lcd, SSD1289_XADDR, column); /* 0-239 */ - ssd1289_putreg(lcd, SSD1289_YADDR, row); /* 0-319 */ -#elif defined(CONFIG_LCD_LANDSCAPE) || defined(CONFIG_LCD_RLANDSCAPE) - ssd1289_putreg(lcd, SSD1289_XADDR, row); /* 0-239 */ - ssd1289_putreg(lcd, SSD1289_YADDR, column); /* 0-319 */ -#endif -} - -/************************************************************************************** - * Name: ssd1289_dumprun - * - * Description: - * Dump the contexts of the run buffer: - * - * run - The buffer in containing the run read to be dumped - * npixels - The number of pixels to dump - * - **************************************************************************************/ - -#if 0 /* Sometimes useful */ -static void ssd1289_dumprun(FAR const char *msg, FAR uint16_t *run, size_t npixels) -{ - int i, j; - - syslog("\n%s:\n", msg); - for (i = 0; i < npixels; i += 16) - { - up_putc(' '); - syslog(" "); - for (j = 0; j < 16; j++) - { - syslog(" %04x", *run++); - } - up_putc('\n'); - } -} -#endif - -/************************************************************************************** - * Name: ssd1289_showrun - * - * Description: - * When LCD debug is enabled, try to reduce then amount of ouptut data generated by - * ssd1289_putrun and ssd1289_getrun - * - **************************************************************************************/ - -#ifdef CONFIG_DEBUG_LCD -static void ssd1289_showrun(FAR struct ssd1289_dev_s *priv, fb_coord_t row, - fb_coord_t col, size_t npixels, bool put) -{ - fb_coord_t nextrow = priv->lastrow + 1; - - /* Has anything changed (other than the row is the next row in the sequence)? */ - - if (put == priv->put && row == nextrow && col == priv->col && - npixels == priv->npixels) - { - /* No, just update the last row */ - - priv->lastrow = nextrow; - } - else - { - /* Yes... then this is the end of the preceding sequence. Output the last run - * (if there were more than one run in the sequence). - */ - - if (priv->firstrow != priv->lastrow) - { - lcddbg("...\n"); - lcddbg("%s row: %d col: %d npixels: %d\n", - priv->put ? "PUT" : "GET", - priv->lastrow, priv->col, priv->npixels); - } - - /* And we are starting a new sequence. Output the first run of the - * new sequence - */ - - lcddbg("%s row: %d col: %d npixels: %d\n", - put ? "PUT" : "GET", row, col, npixels); - - /* And save information about the run so that we can detect continuations - * of the sequence. - */ - - priv->put = put; - priv->firstrow = row; - priv->lastrow = row; - priv->col = col; - priv->npixels = npixels; - } -} -#endif - -/************************************************************************************** - * Name: ssd1289_putrun - * - * Description: - * This method can be used to write a partial raster line to the LCD: - * - * row - Starting row to write to (range: 0 <= row < yres) - * col - Starting column to write to (range: 0 <= col <= xres-npixels) - * buffer - The buffer containing the run to be written to the LCD - * npixels - The number of pixels to write to the LCD - * (range: 0 < npixels <= xres-col) - * - **************************************************************************************/ - -static int ssd1289_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer, - size_t npixels) -{ - FAR struct ssd1289_dev_s *priv = &g_lcddev; - FAR struct ssd1289_lcd_s *lcd = priv->lcd; - FAR const uint16_t *src = (FAR const uint16_t*)buffer; - int i; - - /* Buffer must be provided and aligned to a 16-bit address boundary */ - - ssd1289_showrun(priv, row, col, npixels, true); - DEBUGASSERT(buffer && ((uintptr_t)buffer & 1) == 0); - - /* Select the LCD */ - - lcd->select(lcd); - - /* Write the run to GRAM. */ - -#ifdef CONFIG_LCD_LANDSCAPE - /* Convert coordinates -- Here the edge away from the row of buttons on - * the STM3240G-EVAL is used as the top. - */ - - /* Write the GRAM data, manually incrementing X */ - - for (i = 0; i < npixels; i++) - { - /* Write the next pixel to this position */ - - ssd1289_setcursor(lcd, col, row); - ssd1289_gramselect(lcd); - ssd1289_gramwrite(lcd, *src); - - /* Increment to the next column */ - - src++; - col++; - } -#elif defined(CONFIG_LCD_RLANDSCAPE) - /* Convert coordinates -- Here the edge next to the row of buttons on - * the STM3240G-EVAL is used as the top. - */ - - col = (SSD1289_XRES-1) - col; - row = (SSD1289_YRES-1) - row; - - /* Set the cursor position */ - - ssd1289_setcursor(lcd, col, row); - - /* Then write the GRAM data, auto-decrementing X */ - - ssd1289_gramselect(lcd); - for (i = 0; i < npixels; i++) - { - /* Write the next pixel to this position (auto-decrements to the next column) */ - - ssd1289_gramwrite(lcd, *src); - src++; - } -#elif defined(CONFIG_LCD_PORTRAIT) - /* Convert coordinates. In this configuration, the top of the display is to the left - * of the buttons (if the board is held so that the buttons are at the botton of the - * board). - */ - - col = (SSD1289_XRES-1) - col; - - /* Then write the GRAM data, manually incrementing Y (which is col) */ - - for (i = 0; i < npixels; i++) - { - /* Write the next pixel to this position */ - - ssd1289_setcursor(lcd, row, col); - ssd1289_gramselect(lcd); - ssd1289_gramwrite(lcd, *src); - - /* Increment to the next column */ - - src++; - col--; - } -#else /* CONFIG_LCD_RPORTRAIT */ - /* Convert coordinates. In this configuration, the top of the display is to the right - * of the buttons (if the board is held so that the buttons are at the botton of the - * board). - */ - - row = (SSD1289_YRES-1) - row; - - /* Then write the GRAM data, manually incrementing Y (which is col) */ - - for (i = 0; i < npixels; i++) - { - /* Write the next pixel to this position */ - - ssd1289_setcursor(lcd, row, col); - ssd1289_gramselect(lcd); - ssd1289_gramwrite(lcd, *src); - - /* Decrement to the next column */ - - src++; - col++; - } -#endif - - /* De-select the LCD */ - - lcd->deselect(lcd); - return OK; -} - -/************************************************************************************** - * Name: ssd1289_getrun - * - * Description: - * This method can be used to read a partial raster line from the LCD: - * - * 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) - * - **************************************************************************************/ - -static int ssd1289_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer, - size_t npixels) -{ -#ifndef CONFIG_LCD_NOGETRUN - FAR struct ssd1289_dev_s *priv = &g_lcddev; - FAR struct ssd1289_lcd_s *lcd = priv->lcd; - FAR uint16_t *dest = (FAR uint16_t*)buffer; - uint16_t accum; - int i; - - /* Buffer must be provided and aligned to a 16-bit address boundary */ - - ssd1289_showrun(priv, row, col, npixels, false); - DEBUGASSERT(buffer && ((uintptr_t)buffer & 1) == 0); - - /* Select the LCD */ - - lcd->select(lcd); - - /* Read the run from GRAM. */ - -#ifdef CONFIG_LCD_LANDSCAPE - /* Convert coordinates -- Here the edge away from the row of buttons on - * the STM3240G-EVAL is used as the top. - */ - - for (i = 0; i < npixels; i++) - { - /* Read the next pixel from this position */ - - ssd1289_setcursor(lcd, row, col); - ssd1289_gramselect(lcd); - ssd1289_readsetup(lcd, &accum); - *dest++ = ssd1289_gramread(lcd, &accum); - - /* Increment to the next column */ - - col++; - } -#elif defined(CONFIG_LCD_RLANDSCAPE) - /* Convert coordinates -- Here the edge next to the row of buttons on - * the STM3240G-EVAL is used as the top. - */ - - col = (SSD1289_XRES-1) - col; - row = (SSD1289_YRES-1) - row; - - /* Set the cursor position */ - - ssd1289_setcursor(lcd, col, row); - - /* Then read the GRAM data, auto-decrementing Y */ - - ssd1289_gramselect(lcd); - - /* Prime the pump for unaligned read data */ - - ssd1289_readsetup(lcd, &accum); - - for (i = 0; i < npixels; i++) - { - /* Read the next pixel from this position (autoincrements to the next row) */ - - *dest++ = ssd1289_gramread(lcd, &accum); - } -#elif defined(CONFIG_LCD_PORTRAIT) - /* Convert coordinates. In this configuration, the top of the display is to the left - * of the buttons (if the board is held so that the buttons are at the botton of the - * board). - */ - - col = (SSD1289_XRES-1) - col; - - /* Then read the GRAM data, manually incrementing Y (which is col) */ - - for (i = 0; i < npixels; i++) - { - /* Read the next pixel from this position */ - - ssd1289_setcursor(lcd, row, col); - ssd1289_gramselect(lcd); - ssd1289_readsetup(lcd, &accum); - *dest++ = ssd1289_gramread(lcd, &accum); - - /* Increment to the next column */ - - col--; - } -#else /* CONFIG_LCD_RPORTRAIT */ - /* Convert coordinates. In this configuration, the top of the display is to the right - * of the buttons (if the board is held so that the buttons are at the botton of the - * board). - */ - - row = (SSD1289_YRES-1) - row; - - /* Then write the GRAM data, manually incrementing Y (which is col) */ - - for (i = 0; i < npixels; i++) - { - /* Write the next pixel to this position */ - - ssd1289_setcursor(lcd, row, col); - ssd1289_gramselect(lcd); - ssd1289_readsetup(lcd, &accum); - *dest++ = ssd1289_gramread(lcd, &accum); - - /* Decrement to the next column */ - - col++; - } -#endif - - /* De-select the LCD */ - - lcd->deselect(lcd); - return OK; -#else - return -ENOSYS; -#endif -} - -/************************************************************************************** - * Name: ssd1289_getvideoinfo - * - * Description: - * Get information about the LCD video controller configuration. - * - **************************************************************************************/ - -static int ssd1289_getvideoinfo(FAR struct lcd_dev_s *dev, - FAR struct fb_videoinfo_s *vinfo) -{ - DEBUGASSERT(dev && vinfo); - lcdvdbg("fmt: %d xres: %d yres: %d nplanes: 1\n", - SSD1289_COLORFMT, SSD1289_XRES, SSD1289_YRES); - - vinfo->fmt = SSD1289_COLORFMT; /* Color format: RGB16-565: RRRR RGGG GGGB BBBB */ - vinfo->xres = SSD1289_XRES; /* Horizontal resolution in pixel columns */ - vinfo->yres = SSD1289_YRES; /* Vertical resolution in pixel rows */ - vinfo->nplanes = 1; /* Number of color planes supported */ - return OK; -} - -/************************************************************************************** - * Name: ssd1289_getplaneinfo - * - * Description: - * Get information about the configuration of each LCD color plane. - * - **************************************************************************************/ - -static int ssd1289_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planeno, - FAR struct lcd_planeinfo_s *pinfo) -{ - FAR struct ssd1289_dev_s *priv = (FAR struct ssd1289_dev_s *)dev; - - DEBUGASSERT(dev && pinfo && planeno == 0); - lcdvdbg("planeno: %d bpp: %d\n", planeno, SSD1289_BPP); - - pinfo->putrun = ssd1289_putrun; /* Put a run into LCD memory */ - pinfo->getrun = ssd1289_getrun; /* Get a run from LCD memory */ - pinfo->buffer = (uint8_t*)priv->runbuffer; /* Run scratch buffer */ - pinfo->bpp = SSD1289_BPP; /* Bits-per-pixel */ - return OK; -} - -/************************************************************************************** - * Name: ssd1289_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. - * - **************************************************************************************/ - -static int ssd1289_getpower(FAR struct lcd_dev_s *dev) -{ - lcdvdbg("power: %d\n", 0); - return g_lcddev.power; -} - -/************************************************************************************** - * Name: ssd1289_poweroff - * - * Description: - * Enable/disable LCD panel power (0: full off - CONFIG_LCD_MAXPOWER: full on). On - * backlit LCDs, this setting may correspond to the backlight setting. - * - **************************************************************************************/ - -static int ssd1289_poweroff(FAR struct ssd1289_lcd_s *lcd) -{ - /* Set the backlight off */ - - lcd->backlight(lcd, 0); - - /* Turn the display off */ - - ssd1289_putreg(lcd, SSD1289_DSPCTRL, 0); - - /* Remember the power off state */ - - g_lcddev.power = 0; - return OK; -} - -/************************************************************************************** - * Name: ssd1289_setpower - * - * Description: - * Enable/disable LCD panel power (0: full off - CONFIG_LCD_MAXPOWER: full on). On - * backlit LCDs, this setting may correspond to the backlight setting. - * - **************************************************************************************/ - -static int ssd1289_setpower(FAR struct lcd_dev_s *dev, int power) -{ - FAR struct ssd1289_dev_s *priv = (FAR struct ssd1289_dev_s *)dev; - FAR struct ssd1289_lcd_s *lcd = priv->lcd; - - lcdvdbg("power: %d\n", power); - DEBUGASSERT((unsigned)power <= CONFIG_LCD_MAXPOWER); - - /* Set new power level */ - - if (power > 0) - { - /* Set the backlight level */ - - lcd->backlight(lcd, power); - - /* Then turn the display on: - * D=ON(3) CM=0 DTE=1 GON=1 SPT=0 VLE=0 PT=0 - */ - - ssd1289_putreg(lcd, SSD1289_DSPCTRL, - (SSD1289_DSPCTRL_ON | SSD1289_DSPCTRL_GON | - SSD1289_DSPCTRL_DTE | SSD1289_DSPCTRL_VLE(0))); - - g_lcddev.power = power; - } - else - { - /* Turn the display off */ - - ssd1289_poweroff(lcd); - } - - return OK; -} - -/************************************************************************************** - * Name: ssd1289_getcontrast - * - * Description: - * Get the current contrast setting (0-CONFIG_LCD_MAXCONTRAST). - * - **************************************************************************************/ - -static int ssd1289_getcontrast(FAR struct lcd_dev_s *dev) -{ - lcdvdbg("Not implemented\n"); - return -ENOSYS; -} - -/************************************************************************************** - * Name: ssd1289_setcontrast - * - * Description: - * Set LCD panel contrast (0-CONFIG_LCD_MAXCONTRAST). - * - **************************************************************************************/ - -static int ssd1289_setcontrast(FAR struct lcd_dev_s *dev, unsigned int contrast) -{ - lcdvdbg("contrast: %d\n", contrast); - return -ENOSYS; -} - -/************************************************************************************** - * Name: ssd1289_hwinitialize - * - * Description: - * Initialize the LCD hardware. - * - **************************************************************************************/ - -static inline int ssd1289_hwinitialize(FAR struct ssd1289_dev_s *priv) -{ - FAR struct ssd1289_lcd_s *lcd = priv->lcd; -#ifndef CONFIG_LCD_NOGETRUN - uint16_t id; -#endif - int ret; - - /* Select the LCD */ - - lcd->select(lcd); - - /* Read the device ID. Skip verification of the device ID is the LCD is - * write-only. What choice do we have? - */ - -#ifndef CONFIG_LCD_NOGETRUN - id = ssd1289_readreg(lcd, SSD1289_DEVCODE); - if (id != 0) - { - lcddbg("LCD ID: %04x\n", id); - } - - /* If we could not get the ID, then let's just assume that this is an SSD1289. - * Perhaps we have some early register access issues. This seems to happen. - * But then perhaps we should not even bother to read the device ID at all? - */ - - else - { - lcddbg("No LCD ID, assuming SSD1289\n"); - id = SSD1289_DEVCODE_VALUE; - } - - /* Check if the ID is for the SSD1289 */ - - if (id == SSD1289_DEVCODE_VALUE) -#endif - { - /* LCD controller configuration. Many details of the controller initialization - * must, unfortunately, vary from LCD to LCD. I have looked at the spec and at - * three different drivers for LCDs that have SSD1289 controllers. I have tried - * to summarize these differences as profiles (defined above). Some other - * alternatives are noted below. - * - * Most of the differences between LCDs are nothing more than a few minor bit - * settings. The most significant difference betwen LCD drivers in is the - * manner in which the LCD is powered up and in how the power controls are set. - * My suggestion is that if you have working LCD initialization code, you should - * simply replace the following guesses with your working code. - */ - - /* Most drivers just enable the oscillator */ - -#ifdef SSD1289_USE_SIMPLE_INIT - ssd1289_putreg(lcd, SSD1289_OSCSTART, SSD1289_OSCSTART_OSCEN); -#else - /* But one goes through a more complex start-up sequence. Something like the - * following: - * - * First, put the display in INTERNAL operation: - * D=INTERNAL(1) CM=0 DTE=0 GON=1 SPT=0 VLE=0 PT=0 - */ - - ssd1289_putreg(lcd, SSD1289_DSPCTRL, - (SSD1289_DSPCTRL_INTERNAL | SSD1289_DSPCTRL_GON | - SSD1289_DSPCTRL_VLE(0))); - - /* Then enable the oscillator */ - - ssd1289_putreg(lcd, SSD1289_OSCSTART, SSD1289_OSCSTART_OSCEN); - - /* Turn the display on: - * D=ON(3) CM=0 DTE=0 GON=1 SPT=0 VLE=0 PT=0 - */ - - ssd1289_putreg(lcd, SSD1289_DSPCTRL, - (SSD1289_DSPCTRL_ON | SSD1289_DSPCTRL_GON | - SSD1289_DSPCTRL_VLE(0))); - - /* Take the LCD out of sleep mode */ - - ssd1289_putreg(lcd, SSD1289_SLEEP, 0); - up_mdelay(30); - - /* Turn the display on: - * D=INTERNAL(1) CM=0 DTE=1 GON=1 SPT=0 VLE=0 PT=0 - */ - - ssd1289_putreg(lcd, SSD1289_DSPCTRL, - (SSD1289_DSPCTRL_ON | SSD1289_DSPCTRL_DTE | - SSD1289_DSPCTRL_GON | SSD1289_DSPCTRL_VLE(0))); -#endif - - /* Set up power control registers. There is a lot of variability - * from LCD-to-LCD in how the power registers are configured. - */ - - ssd1289_putreg(lcd, SSD1289_PWRCTRL1, PWRCTRL1_SETTING); - ssd1289_putreg(lcd, SSD1289_PWRCTRL2, PWRCTRL2_SETTING); - - /* One driver adds a delay here.. I doubt that this is really necessary. */ - /* up_mdelay(15); */ - - ssd1289_putreg(lcd, SSD1289_PWRCTRL3, PWRCTRL3_SETTING); - ssd1289_putreg(lcd, SSD1289_PWRCTRL4, PWRCTRL4_SETTING); - ssd1289_putreg(lcd, SSD1289_PWRCTRL5, PWRCTRL5_SETTING); - - /* One driver does an odd setting of the the driver output control. - * No idea why. - */ -#if 0 - ssd1289_putreg(lcd, SSD1289_OUTCTRL, - (SSD1289_OUTCTRL_MUX(12) | SSD1289_OUTCTRL_TB | - SSD1289_OUTCTRL_BGR | SSD1289_OUTCTRL_CAD)); - - /* The same driver does another small delay here */ - - up_mdelay(15); -#endif - - /* After this point, the drivers differ only in some varying register - * bit settings. - */ - - /* Set the driver output control. - * PORTRAIT MODES: - * MUX=319, TB=1, SM=0, BGR=1, CAD=0, REV=1, RL=0 - * LANDSCAPE MODES: - * MUX=319, TB=0, SM=0, BGR=1, CAD=0, REV=1, RL=0 - */ - -#if defined(CONFIG_LCD_PORTRAIT) || defined(CONFIG_LCD_RPORTRAIT) - ssd1289_putreg(lcd, SSD1289_OUTCTRL, - (SSD1289_OUTCTRL_MUX(319) | SSD1289_OUTCTRL_TB | - SSD1289_OUTCTRL_BGR | SSD1289_OUTCTRL_REV); -#else - ssd1289_putreg(lcd, SSD1289_OUTCTRL, - (SSD1289_OUTCTRL_MUX(319) | SSD1289_OUTCTRL_BGR | - SSD1289_OUTCTRL_REV)); -#endif - - /* Set the LCD driving AC waveform - * NW=0, WSMD=0, EOR=1, BC=1, ENWD=0, FLD=0 - */ - - ssd1289_putreg(lcd, SSD1289_ACCTRL, - (SSD1289_ACCTRL_EOR | SSD1289_ACCTRL_BC)); - - /* Take the LCD out of sleep mode (isn't this redundant in the non- - * simple case?) - */ - - ssd1289_putreg(lcd, SSD1289_SLEEP, 0); - - /* Set entry mode */ - -#if defined(CONFIG_LCD_PORTRAIT) || defined(CONFIG_LCD_RPORTRAIT) - /* LG=0, AM=0, ID=3, TY=2, DMODE=0, WMODE=0, OEDEF=0, TRANS=0, DRM=3 - * Alternative TY=2 (But TY only applies in 262K color mode anyway) - */ - - ssd1289_putreg(lcd, SSD1289_ENTRY, - (SSD1289_ENTRY_ID_HINCVINC | SSD1289_ENTRY_TY_C | - SSD1289_ENTRY_DMODE_RAM | SSD1289_ENTRY_DFM_65K)); -#else - /* LG=0, AM=1, ID=3, TY=2, DMODE=0, WMODE=0, OEDEF=0, TRANS=0, DRM=3 */ - /* Alternative TY=2 (But TY only applies in 262K color mode anyway) */ - - ssd1289_putreg(lcd, SSD1289_ENTRY, - (SSD1289_ENTRY_AM | SSD1289_ENTRY_ID_HINCVINC | - SSD1289_ENTRY_TY_C | SSD1289_ENTRY_DMODE_RAM | - SSD1289_ENTRY_DFM_65K)); -#endif - - /* Clear compare registers */ - - ssd1289_putreg(lcd, SSD1289_CMP1, 0); - ssd1289_putreg(lcd, SSD1289_CMP2, 0); - - /* One driver puts a huge, 100 millisecond delay here */ - /* up_mdelay(100); */ - - /* Set Horizontal and vertical porch. - * Horizontal porch: 239 pixels per line, delay=28 - * Vertical porch: VBP=3, XFP=0 - */ - - ssd1289_putreg(lcd, SSD1289_HPORCH, - (28 << SSD1289_HPORCH_HBP_SHIFT) | (239 << SSD1289_HPORCH_XL_SHIFT)); - ssd1289_putreg(lcd, SSD1289_VPORCH, - (3 << SSD1289_VPORCH_VBP_SHIFT) | (0 << SSD1289_VPORCH_XFP_SHIFT)); - - /* Set display control. - * D=ON(3), CM=0 (not 8-color), DTE=1, GON=1, SPT=0, VLE=1 PT=0 - */ - - ssd1289_putreg(lcd, SSD1289_DSPCTRL, - (SSD1289_DSPCTRL_ON | SSD1289_DSPCTRL_DTE | - SSD1289_DSPCTRL_GON | SSD1289_DSPCTRL_VLE(1))); - - /* Frame cycle control. Alternative: SSD1289_FCYCCTRL_DIV8 */ - - ssd1289_putreg(lcd, SSD1289_FCYCCTRL, 0); - - /* Gate scan start position = 0 */ - - ssd1289_putreg(lcd, SSD1289_GSTART, 0); - - /* Clear vertical scrolling */ - - ssd1289_putreg(lcd, SSD1289_VSCROLL1, 0); - ssd1289_putreg(lcd, SSD1289_VSCROLL2, 0); - - /* Setup window 1 (0-319) */ - - ssd1289_putreg(lcd, SSD1289_W1START, 0); - ssd1289_putreg(lcd, SSD1289_W1END, 319); - - /* Disable window 2 (0-0) */ - - ssd1289_putreg(lcd, SSD1289_W2START, 0); - ssd1289_putreg(lcd, SSD1289_W2END, 0); - - /* Horizontal start and end (0-239) */ - - ssd1289_putreg(lcd, SSD1289_HADDR, - (0 << SSD1289_HADDR_HSA_SHIFT) | (239 << SSD1289_HADDR_HEA_SHIFT)); - - /* Vertical start and end (0-319) */ - - ssd1289_putreg(lcd, SSD1289_VSTART, 0); - ssd1289_putreg(lcd, SSD1289_VEND, 319); - - /* Gamma controls */ - - ssd1289_putreg(lcd, SSD1289_GAMMA1, 0x0707); - ssd1289_putreg(lcd, SSD1289_GAMMA2, 0x0204); /* Alternative: 0x0704 */ - ssd1289_putreg(lcd, SSD1289_GAMMA3, 0x0204); - ssd1289_putreg(lcd, SSD1289_GAMMA4, 0x0502); - ssd1289_putreg(lcd, SSD1289_GAMMA5, 0x0507); - ssd1289_putreg(lcd, SSD1289_GAMMA6, 0x0204); - ssd1289_putreg(lcd, SSD1289_GAMMA7, 0x0204); - ssd1289_putreg(lcd, SSD1289_GAMMA8, 0x0502); - ssd1289_putreg(lcd, SSD1289_GAMMA9, 0x0302); - ssd1289_putreg(lcd, SSD1289_GAMMA10, 0x0302); /* Alternative: 0x1f00 */ - - /* Clear write mask */ - - ssd1289_putreg(lcd, SSD1289_WRMASK1, 0); - ssd1289_putreg(lcd, SSD1289_WRMASK2, 0); - - /* Set frame frequency = 65Hz (This should not be necessary since this - * is the default POR value) - */ - - ssd1289_putreg(lcd, SSD1289_FFREQ, SSD1289_FFREQ_OSC_FF65); - - /* Set the cursor at the home position and set the index register to - * the gram data register (I can't imagine these are necessary). - */ - - ssd1289_setcursor(lcd, 0, 0); - ssd1289_gramselect(lcd); - - /* One driver has a 50 msec delay here */ - /* up_mdelay(50); */ - - ret = OK; - } -#ifndef CONFIG_LCD_NOGETRUN - else - { - lcddbg("Unsupported LCD type\n"); - ret = -ENODEV; - } -#endif - - /* De-select the LCD */ - - lcd->deselect(lcd); - return ret; -} - - /************************************************************************************* - * Public Functions - **************************************************************************************/ - -/************************************************************************************** - * Name: ssd1289_lcdinitialize - * - * Description: - * Initialize the LCD 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). - * - **************************************************************************************/ - -FAR struct lcd_dev_s *ssd1289_lcdinitialize(FAR struct ssd1289_lcd_s *lcd) -{ - int ret; - - lcdvdbg("Initializing\n"); - - /* If we ccould support multiple SSD1289 devices, this is where we would allocate - * a new driver data structure... but we can't. Why not? Because of a bad should - * the form of the getrun() and putrun methods. - */ - - FAR struct ssd1289_dev_s *priv = &g_lcddev; - - /* Initialize the driver data structure */ - - priv->dev.getvideoinfo = ssd1289_getvideoinfo; - priv->dev.getplaneinfo = ssd1289_getplaneinfo; - priv->dev.getpower = ssd1289_getpower; - priv->dev.setpower = ssd1289_setpower; - priv->dev.getcontrast = ssd1289_getcontrast; - priv->dev.setcontrast = ssd1289_setcontrast; - priv->lcd = lcd; - - /* Configure and enable LCD */ - - ret = ssd1289_hwinitialize(priv); - if (ret == OK) - { - /* Clear the display (setting it to the color 0=black) */ - - ssd1289_clear(&priv->dev, 0); - - /* Turn the display off */ - - ssd1289_poweroff(lcd); - return &g_lcddev.dev; - } - - return NULL; -} - -/************************************************************************************** - * Name: ssd1289_clear - * - * Description: - * This is a non-standard LCD interface just for the stm3240g-EVAL board. 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. - * - **************************************************************************************/ - -void ssd1289_clear(FAR struct lcd_dev_s *dev, uint16_t color) -{ - FAR struct ssd1289_dev_s *priv = (FAR struct ssd1289_dev_s *)dev; - FAR struct ssd1289_lcd_s *lcd = priv->lcd; - uint32_t i; - - /* Select the LCD and home the cursor position */ - - lcd->select(lcd); - ssd1289_setcursor(lcd, 0, 0); - - /* Prepare to write GRAM data */ - - ssd1289_gramselect(lcd); - - /* Copy color into all of GRAM. Orientation does not matter in this case. */ - - for (i = 0; i < SSD1289_XRES * SSD1289_YRES; i++) - { - ssd1289_gramwrite(lcd, color); - } - - /* De-select the LCD */ - - lcd->deselect(lcd); -} - -#endif /* CONFIG_LCD_SSD1289 */ diff --git a/nuttx/drivers/lcd/ssd1289.h b/nuttx/drivers/lcd/ssd1289.h deleted file mode 100644 index 6d5d1c3cb..000000000 --- a/nuttx/drivers/lcd/ssd1289.h +++ /dev/null @@ -1,425 +0,0 @@ -/************************************************************************************** - * drivers/lcd/ssd1289.h - * Definitions for the Solomon Systech SSD1289 LCD controller - * - * Copyright (C) 2012 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt <gnutt@nuttx.org> - * - * References: SSD1289, Rev 1.3, Apr 2007, Solomon Systech Limited - * - * 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 written 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. - * - **************************************************************************************/ - -#ifndef __DRIVERS_LCD_SSD1289_H -#define __DRIVERS_LCD_SSD1289_H - -/************************************************************************************** - * Included Files - **************************************************************************************/ - -#include <nuttx/config.h> - -#ifdef CONFIG_LCD_SSD1289 - -/************************************************************************************** - * Pre-processor Definitions - **************************************************************************************/ - -/* SSD1289 Register Addresses (All with DC=1) */ - -#define SSD1289_OSCSTART 0x00 /* Oscillation Start (write) */ -#define SSD1289_DEVCODE 0x00 /* Oscillation Start (read) */ -#define SSD1289_OUTCTRL 0x01 /* Driver output control */ -#define SSD1289_ACCTRL 0x02 /* LCD drive AC control */ -#define SSD1289_PWRCTRL1 0x03 /* Power control 1 */ -#define SSD1289_CMP1 0x05 /* Compare register 1 */ -#define SSD1289_CMP2 0x06 /* Compare register 2 */ -#define SSD1289_DSPCTRL 0x07 /* Display control */ -#define SSD1289_FCYCCTRL 0x0b /* Frame cycle control */ -#define SSD1289_PWRCTRL2 0x0c /* Power control 2 */ -#define SSD1289_PWRCTRL3 0x0d /* Power control 3 */ -#define SSD1289_PWRCTRL4 0x0e /* Power control 4 */ -#define SSD1289_GSTART 0x0f /* Gate scan start position */ -#define SSD1289_SLEEP 0x10 /* Sleep mode */ -#define SSD1289_ENTRY 0x11 /* Entry mode */ -#define SSD1289_OPT3 0x12 /* Optimize Access Speed 3 */ -#define SSD1289_GIFCTRL 0x15 /* Generic Interface Control */ -#define SSD1289_HPORCH 0x16 /* Horizontal Porch */ -#define SSD1289_VPORCH 0x17 /* Vertical Porch */ -#define SSD1289_PWRCTRL5 0x1e /* Power control 5 */ -#define SSD1289_DATA 0x22 /* RAM data/write data */ -#define SSD1289_WRMASK1 0x23 /* RAM write data mask 1 */ -#define SSD1289_WRMASK2 0x24 /* RAM write data mask 2 */ -#define SSD1289_FFREQ 0x25 /* Frame Frequency */ -#define SSD1289_VCOMOTP1 0x28 /* VCOM OTP */ -#define SSD1289_OPT1 0x28 /* Optimize Access Speed 1 */ -#define SSD1289_VCOMOTP2 0x29 /* VCOM OTP */ -#define SSD1289_OPT2 0x2f /* Optimize Access Speed 2 */ -#define SSD1289_GAMMA1 0x30 /* Gamma control 1 */ -#define SSD1289_GAMMA2 0x31 /* Gamma control 2 */ -#define SSD1289_GAMMA3 0x32 /* Gamma control 3 */ -#define SSD1289_GAMMA4 0x33 /* Gamma control 4 */ -#define SSD1289_GAMMA5 0x34 /* Gamma control 5 */ -#define SSD1289_GAMMA6 0x35 /* Gamma control 6 */ -#define SSD1289_GAMMA7 0x36 /* Gamma control 7 */ -#define SSD1289_GAMMA8 0x37 /* Gamma control 8 */ -#define SSD1289_GAMMA9 0x3a /* Gamma control 9 */ -#define SSD1289_GAMMA10 0x3b /* Gamma control 10 */ -#define SSD1289_VSCROLL1 0x41 /* Vertical scroll control 1 */ -#define SSD1289_VSCROLL2 0x42 /* Vertical scroll control 2 */ -#define SSD1289_HADDR 0x44 /* Horizontal RAM address position */ -#define SSD1289_VSTART 0x45 /* Vertical RAM address start position */ -#define SSD1289_VEND 0x46 /* Vertical RAM address end position */ -#define SSD1289_W1START 0x48 /* First window start */ -#define SSD1289_W1END 0x49 /* First window end */ -#define SSD1289_W2START 0x4a /* Second window start */ -#define SSD1289_W2END 0x4b /* Second window end */ -#define SSD1289_XADDR 0x4e /* Set GDDRAM X address counter */ -#define SSD1289_YADDR 0x4f /* Set GDDRAM Y address counter */ - -/* SSD1289 Register Bit definitions */ - -/* Index register (DC=0) */ - -#define SSD1289_INDEX_MASK 0xff - -/* Device code (read) */ - -#define SSD1289_DEVCODE_VALUE 0x8989 - -/* Oscillation Start (write) */ - -#define SSD1289_OSCSTART_OSCEN (1 << 0) /* Enable oscillator */ - -/* Driver output control */ - -#define SSD1289_OUTCTRL_MUX_SHIFT (0) /* Number of lines for the LCD driver */ -#define SSD1289_OUTCTRL_MUX_MASK (0x1ff << SSD1289_OUTCTRL_MUX_SHIFT) -# define SSD1289_OUTCTRL_MUX(n) ((n) << SSD1289_OUTCTRL_MUX_SHIFT) -#define SSD1289_OUTCTRL_TB (1 << 9) /* Selects the output shift direction of the gate driver */ -#define SSD1289_OUTCTRL_SM (1 << 10) /* Scanning order of gate driver */ -#define SSD1289_OUTCTRL_BGR (1 << 11) /* Order from RGB to BGR in 18-bit GDDRAM data */ -#define SSD1289_OUTCTRL_CAD (1 << 12) /* Retention capacitor configuration of the TFT panel */ -#define SSD1289_OUTCTRL_REV (1 << 13) /* Reversed display */ -#define SSD1289_OUTCTRL_RL (1 << 14) /* RL pin state */ - -/* LCD drive AC control */ - -#define SSD1289_ACCTRL_NW_SHIFT (0) /* Number of lines to alternate in N-line inversion */ -#define SSD1289_ACCTRL_NW_MASK (0xff << SSD1289_ACCTRL_NW_SHIFT) -#define SSD1289_ACCTRL_WSMD (1 << 8) /* Waveform of WSYNC output */ -#define SSD1289_ACCTRL_EOR (1 << 9) /* EOR signals */ -#define SSD1289_ACCTRL_BC (1 << 10) /* Select the liquid crystal drive waveform */ -#define SSD1289_ACCTRL_ENWS (1 << 11) /* Enables WSYNC output pin */ -#define SSD1289_ACCTRL_FLD (1 << 12) /* Set display in interlace drive mode */ - -/* Power control 1 */ - -#define SSD1289_PWRCTRL1_AP_SHIFT (1) /* Current from internal operational amplifier */ -#define SSD1289_PWRCTRL1_AP_MASK (7 << SSD1289_PWRCTRL1_AP_SHIFT) -# define SSD1289_PWRCTRL1_AP_LEAST (0 << SSD1289_PWRCTRL1_AP_SHIFT) -# define SSD1289_PWRCTRL1_AP_SMALL (1 << SSD1289_PWRCTRL1_AP_SHIFT) -# define SSD1289_PWRCTRL1_AP_SMMED (2 << SSD1289_PWRCTRL1_AP_SHIFT) -# define SSD1289_PWRCTRL1_AP_MEDIUM (3 << SSD1289_PWRCTRL1_AP_SHIFT) -# define SSD1289_PWRCTRL1_AP_MEDLG (4 << SSD1289_PWRCTRL1_AP_SHIFT) -# define SSD1289_PWRCTRL1_AP_LARGE (5 << SSD1289_PWRCTRL1_AP_SHIFT) -# define SSD1289_PWRCTRL1_AP_LGMX (6 << SSD1289_PWRCTRL1_AP_SHIFT) -# define SSD1289_PWRCTRL1_AP_MAX (7 << SSD1289_PWRCTRL1_AP_SHIFT) -#define SSD1289_PWRCTRL1_DC_SHIFT (4) /* Set the step-up cycle of the step-up circuit for 262k-color mode */ -#define SSD1289_PWRCTRL1_DC_MASK (15 << SSD1289_PWRCTRL1_DC_SHIFT) -# define SSD1289_PWRCTRL1_DC_FLINEx24 (0 << SSD1289_PWRCTRL1_DC_SHIFT) -# define SSD1289_PWRCTRL1_DC_FLINEx16 (1 << SSD1289_PWRCTRL1_DC_SHIFT) -# define SSD1289_PWRCTRL1_DC_FLINEx12 (2 << SSD1289_PWRCTRL1_DC_SHIFT) -# define SSD1289_PWRCTRL1_DC_FLINEx8 (3 << SSD1289_PWRCTRL1_DC_SHIFT) -# define SSD1289_PWRCTRL1_DC_FLINEx6 (4 << SSD1289_PWRCTRL1_DC_SHIFT) -# define SSD1289_PWRCTRL1_DC_FLINEx5 (5 << SSD1289_PWRCTRL1_DC_SHIFT) -# define SSD1289_PWRCTRL1_DC_FLINEx4 (6 << SSD1289_PWRCTRL1_DC_SHIFT) -# define SSD1289_PWRCTRL1_DC_FLINEx3 (7 << SSD1289_PWRCTRL1_DC_SHIFT) -# define SSD1289_PWRCTRL1_DC_FLINEx2 (8 << SSD1289_PWRCTRL1_DC_SHIFT) -# define SSD1289_PWRCTRL1_DC_FLINEx1 (9 << SSD1289_PWRCTRL1_DC_SHIFT) -# define SSD1289_PWRCTRL1_DC_FOSd4 (10 << SSD1289_PWRCTRL1_DC_SHIFT) -# define SSD1289_PWRCTRL1_DC_FOSd6 (11 << SSD1289_PWRCTRL1_DC_SHIFT) -# define SSD1289_PWRCTRL1_DC_FOSd8 (12 << SSD1289_PWRCTRL1_DC_SHIFT) -# define SSD1289_PWRCTRL1_DC_FOSd10 (13 << SSD1289_PWRCTRL1_DC_SHIFT) -# define SSD1289_PWRCTRL1_DC_FOSd12 (14 << SSD1289_PWRCTRL1_DC_SHIFT) -# define SSD1289_PWRCTRL1_DC_FOSd16 (15 << SSD1289_PWRCTRL1_DC_SHIFT) -#define SSD1289_PWRCTRL1_BT_SHIFT (9) /* Control the step-up factor of the step-up circuit */ -#define SSD1289_PWRCTRL1_BT_MASK (7 << SSD1289_PWRCTRL1_BT_SHIFT) -# define SSD1289_PWRCTRL1_BT_p6m5 (0 << SSD1289_PWRCTRL1_BT_SHIFT) -# define SSD1289_PWRCTRL1_BT_p6m4 (1 << SSD1289_PWRCTRL1_BT_SHIFT) -# define SSD1289_PWRCTRL1_BT_p6m6 (2 << SSD1289_PWRCTRL1_BT_SHIFT) -# define SSD1289_PWRCTRL1_BT_p5m5 (3 << SSD1289_PWRCTRL1_BT_SHIFT) -# define SSD1289_PWRCTRL1_BT_p5m4 (4 << SSD1289_PWRCTRL1_BT_SHIFT) -# define SSD1289_PWRCTRL1_BT_p5m3 (5 << SSD1289_PWRCTRL1_BT_SHIFT) -# define SSD1289_PWRCTRL1_BT_p4m4 (6 << SSD1289_PWRCTRL1_BT_SHIFT) -# define SSD1289_PWRCTRL1_BT_p4m3 (7 << SSD1289_PWRCTRL1_BT_SHIFT) -#define SSD1289_PWRCTRL1_DCT_SHIFT (12) /* Step-up cycle of the step-up circuit for 8-color mode */ -#define SSD1289_PWRCTRL1_DCT_MASK (15 << SSD1289_PWRCTRL1_DCT_SHIFT) -# define SSD1289_PWRCTRL1_DCT_FLINEx24 (0 << SSD1289_PWRCTRL1_DCT_SHIFT) -# define SSD1289_PWRCTRL1_DCT_FLINEx16 (1 << SSD1289_PWRCTRL1_DCT_SHIFT) -# define SSD1289_PWRCTRL1_DCT_FLINEx12 (2 << SSD1289_PWRCTRL1_DCT_SHIFT) -# define SSD1289_PWRCTRL1_DCT_FLINEx8 (3 << SSD1289_PWRCTRL1_DCT_SHIFT) -# define SSD1289_PWRCTRL1_DCT_FLINEx6 (4 << SSD1289_PWRCTRL1_DCT_SHIFT) -# define SSD1289_PWRCTRL1_DCT_FLINEx5 (5 << SSD1289_PWRCTRL1_DCT_SHIFT) -# define SSD1289_PWRCTRL1_DCT_FLINEx4 (6 << SSD1289_PWRCTRL1_DCT_SHIFT) -# define SSD1289_PWRCTRL1_DCT_FLINEx3 (7 << SSD1289_PWRCTRL1_DCT_SHIFT) -# define SSD1289_PWRCTRL1_DCT_FLINEx2 (8 << SSD1289_PWRCTRL1_DCT_SHIFT) -# define SSD1289_PWRCTRL1_DCT_FLINEx1 (9 << SSD1289_PWRCTRL1_DCT_SHIFT) -# define SSD1289_PWRCTRL1_DCT_FOSd4 (10 << SSD1289_PWRCTRL1_DCT_SHIFT) -# define SSD1289_PWRCTRL1_DCT_FOSd6 (11 << SSD1289_PWRCTRL1_DCT_SHIFT) -# define SSD1289_PWRCTRL1_DCT_FOSd8 (12 << SSD1289_PWRCTRL1_DCT_SHIFT) -# define SSD1289_PWRCTRL1_DCT_FOSd10 (13 << SSD1289_PWRCTRL1_DCT_SHIFT) -# define SSD1289_PWRCTRL1_DCT_FOSd12 (14 << SSD1289_PWRCTRL1_DCT_SHIFT) -# define SSD1289_PWRCTRL1_DCT_FOSd16 (15 << SSD1289_PWRCTRL1_DCT_SHIFT) - -/* Compare register 1 and 2 */ - -#define SSD1289_CMP1_CPG_SHIFT (2) -#define SSD1289_CMP1_CPG_MASK (0x3f << SSD1289_CMP1_CPG_SHIFT) -#define SSD1289_CMP1_CPR_SHIFT (10) -#define SSD1289_CMP1_CPR_MASK (0x3f << SSD1289_CMP1_CPR_SHIFT) - -#define SSD1289_CMP2_CPB_SHIFT (2) -#define SSD1289_CMP2_CPB_MASK (0x3f << SSD1289_CMP2_CPB_SHIFT) - -/* Display control */ - -#define SSD1289_DSPCTRL_D_SHIFT (0) /* Display control */ -#define SSD1289_DSPCTRL_D_MASK (3 << SSD1289_DSPCTRL_D_SHIFT) -# define SSD1289_DSPCTRL_OFF (0 << SSD1289_DSPCTRL_D_SHIFT) -# define SSD1289_DSPCTRL_INTERNAL (1 << SSD1289_DSPCTRL_D_SHIFT) -# define SSD1289_DSPCTRL_ON (3 << SSD1289_DSPCTRL_D_SHIFT) -#define SSD1289_DSPCTRL_CM (1 << 3) /* 8-color mode setting */ -#define SSD1289_DSPCTRL_DTE (1 << 4) /* Selected gate level */ -#define SSD1289_DSPCTRL_GON (1 << 5) /* Gate off level */ -#define SSD1289_DSPCTRL_SPT (1 << 8) /* 2-division LCD drive */ -#define SSD1289_DSPCTRL_VLE_SHIFT (9) /* Vertical scroll control */ -#define SSD1289_DSPCTRL_VLE_MASK (3 << SSD1289_DSPCTRL_VLE_SHIFT) -# define SSD1289_DSPCTRL_VLE(n) ((n) << SSD1289_DSPCTRL_VLE_SHIFT) -#define SSD1289_DSPCTRL_PT_SHIFT (11) /* Normalize the source outputs */ -#define SSD1289_DSPCTRL_PT_MASK (3 << SSD1289_DSPCTRL_PT_SHIFT) -# define SSD1289_DSPCTRL_PT(n) ((n) << SSD1289_DSPCTRL_PT_SHIFT) - -/* Frame cycle control */ - -#define SSD1289_FCYCCTRL_RTN_SHIFT (0) /* Number of clocks in each line */ -#define SSD1289_FCYCCTRL_RTN_MASK (3 << SSD1289_FCYCCTRL_RTN_SHIFT) -# define SSD1289_FCYCCTRL_RTN(n) (((n)-16) << SSD1289_FCYCCTRL_RTN_SHIFT) -#define SSD1289_FCYCCTRL_SRTN (1 << 4) /* When SRTN =1, RTN3-0 value will be count */ -#define SSD1289_FCYCCTRL_SDIV (1 << 5) /* When SDIV = 1, DIV1-0 value will be count */ -#define SSD1289_FCYCCTRL_DIV_SHIFT (6) /* Set the division ratio of clocks */ -#define SSD1289_FCYCCTRL_DIV_MASK (3 << SSD1289_FCYCCTRL_DIV_SHIFT) -# define SSD1289_FCYCCTRL_DIV1 (0 << SSD1289_FCYCCTRL_DIV_SHIFT) -# define SSD1289_FCYCCTRL_DIV2 (1 << SSD1289_FCYCCTRL_DIV_SHIFT) -# define SSD1289_FCYCCTRL_DIV4 (2 << SSD1289_FCYCCTRL_DIV_SHIFT) -# define SSD1289_FCYCCTRL_DIV8 (3 << SSD1289_FCYCCTRL_DIV_SHIFT) -#define SSD1289_FCYCCTRL_EQ_SHIFT (8) /* Sets the equalizing period */ -#define SSD1289_FCYCCTRL_EQ_MASK (3 << SSD1289_FCYCCTRL_EQ_SHIFT) -# define SSD1289_FCYCCTRL_EQ(n) (((n)-1) << SSD1289_FCYCCTRL_EQ_SHIFT) /* n = 2-8 clocks */ -#define SSD1289_FCYCCTRL_SDT_SHIFT (12) /* Set delay amount from the gate output */ -#define SSD1289_FCYCCTRL_SDT_MASK (3 << SSD1289_FCYCCTRL_SDT_SHIFT) -# define SSD1289_FCYCCTRL_SDT(n) ((n) << SSD1289_FCYCCTRL_SDT_SHIFT) /* n = 1-3 clocks */ -#define SSD1289_FCYCCTRL_NO_SHIFT (14) /* Sets amount of non-overlap of the gate output */ -#define SSD1289_FCYCCTRL_NO_MASK (3 << SSD1289_FCYCCTRL_NO_SHIFT) -# define SSD1289_FCYCCTRL_NO(n) ((n) << SSD1289_FCYCCTRL_NO_SHIFT) /* n = 1-3 clocks */ - -/* Power control 2 */ - -#define SSD1289_PWRCTRL2_VRC_SHIFT (0) /* Adjust VCIX2 output voltage */ -#define SSD1289_PWRCTRL2_VRC_MASK (7 << SSD1289_PWRCTRL2_VRC_SHIFT) -# define SSD1289_PWRCTRL2_VRC_5p1V (0 << SSD1289_PWRCTRL2_VRC_SHIFT) -# define SSD1289_PWRCTRL2_VRC_5p2V (1 << SSD1289_PWRCTRL2_VRC_SHIFT) -# define SSD1289_PWRCTRL2_VRC_5p3V (2 << SSD1289_PWRCTRL2_VRC_SHIFT) -# define SSD1289_PWRCTRL2_VRC_5p4V (3 << SSD1289_PWRCTRL2_VRC_SHIFT) -# define SSD1289_PWRCTRL2_VRC_5p5V (4 << SSD1289_PWRCTRL2_VRC_SHIFT) -# define SSD1289_PWRCTRL2_VRC_5p6V (5 << SSD1289_PWRCTRL2_VRC_SHIFT) -# define SSD1289_PWRCTRL2_VRC_5p7V (6 << SSD1289_PWRCTRL2_VRC_SHIFT) -# define SSD1289_PWRCTRL2_VRC_5p8V (7 << SSD1289_PWRCTRL2_VRC_SHIFT) - -/* Power control 3 */ - -#define SSD1289_PWRCTRL3_VRH_SHIFT (0) /* Set amplitude magnification of VLCD63 */ -#define SSD1289_PWRCTRL3_VRH_MASK (15 << SSD1289_PWRCTRL3_VRH_SHIFT) -# define SSD1289_PWRCTRL3_VRH_x1p540 (0 << SSD1289_PWRCTRL3_VRH_SHIFT) -# define SSD1289_PWRCTRL3_VRH_x1p620 (1 << SSD1289_PWRCTRL3_VRH_SHIFT) -# define SSD1289_PWRCTRL3_VRH_x1p700 (2 << SSD1289_PWRCTRL3_VRH_SHIFT) -# define SSD1289_PWRCTRL3_VRH_x1p780 (3 << SSD1289_PWRCTRL3_VRH_SHIFT) -# define SSD1289_PWRCTRL3_VRH_x1p850 (4 << SSD1289_PWRCTRL3_VRH_SHIFT) -# define SSD1289_PWRCTRL3_VRH_x1p930 (5 << SSD1289_PWRCTRL3_VRH_SHIFT) -# define SSD1289_PWRCTRL3_VRH_x2p020 (6 << SSD1289_PWRCTRL3_VRH_SHIFT) -# define SSD1289_PWRCTRL3_VRH_x2p090 (7 << SSD1289_PWRCTRL3_VRH_SHIFT) -# define SSD1289_PWRCTRL3_VRH_x2p165 (8 << SSD1289_PWRCTRL3_VRH_SHIFT) -# define SSD1289_PWRCTRL3_VRH_x2p245 (9 << SSD1289_PWRCTRL3_VRH_SHIFT) -# define SSD1289_PWRCTRL3_VRH_x2p335 (10 << SSD1289_PWRCTRL3_VRH_SHIFT) -# define SSD1289_PWRCTRL3_VRH_x2p400 (11 << SSD1289_PWRCTRL3_VRH_SHIFT) -# define SSD1289_PWRCTRL3_VRH_x2p500 (12 << SSD1289_PWRCTRL3_VRH_SHIFT) -# define SSD1289_PWRCTRL3_VRH_x2p570 (13 << SSD1289_PWRCTRL3_VRH_SHIFT) -# define SSD1289_PWRCTRL3_VRH_x2p645 (14 << SSD1289_PWRCTRL3_VRH_SHIFT) -# define SSD1289_PWRCTRL3_VRH_x2p725 (15 << SSD1289_PWRCTRL3_VRH_SHIFT) - -/* Power control 4 */ - -#define SSD1289_PWRCTRL4_VDV_SHIFT (8) /* Set amplitude magnification of VLCD63 */ -#define SSD1289_PWRCTRL4_VDV_MASK (32 << SSD1289_PWRCTRL4_VDV_SHIFT) -# define SSD1289_PWRCTRL4_VDV(n) ((n) << SSD1289_PWRCTRL4_VDV_SHIFT) -#define SSD1289_PWRCTRL4_VCOMG (1 << 13) /* VcomL variable */ - -/* Gate scan start position */ - -#define SSD1289_GSTART_MASK 0x1ff - -/* Sleep mode */ - -#define SSD1289_SLEEP_ON (1 << 0) - -/* Entry mode */ - -#define SSD1289_ENTRY_LG_SHIFT (0) /* Write after comparing */ -#define SSD1289_ENTRY_LG_MASK (7 << SSD1289_ENTRY_LG_SHIFT) -#define SSD1289_ENTRY_AM (1 << 3) /* Address counter direction */ -#define SSD1289_ENTRY_ID_SHIFT (4) /* Address increment mode */ -#define SSD1289_ENTRY_ID_MASK (3 << SSD1289_ENTRY_ID_SHIFT) -# define SSD1289_ENTRY_ID_HDECVDEC (0 << SSD1289_ENTRY_ID_SHIFT) -# define SSD1289_ENTRY_ID_HINCVDEC (1 << SSD1289_ENTRY_ID_SHIFT) -# define SSD1289_ENTRY_ID_HDECVINC (2 << SSD1289_ENTRY_ID_SHIFT) -# define SSD1289_ENTRY_ID_HINCVINC (3 << SSD1289_ENTRY_ID_SHIFT) -#define SSD1289_ENTRY_TY_SHIFT (6) /* RAM data write method */ -#define SSD1289_ENTRY_TY_MASK (3 << SSD1289_ENTRY_TY_SHIFT) -# define SSD1289_ENTRY_TY_A (0 << SSD1289_ENTRY_TY_SHIFT) -# define SSD1289_ENTRY_TY_B (1 << SSD1289_ENTRY_TY_SHIFT) -# define SSD1289_ENTRY_TY_C (2 << SSD1289_ENTRY_TY_SHIFT) -#define SSD1289_ENTRY_DMODE_SHIFT (8) /* Data display mode */ -#define SSD1289_ENTRY_DMODE_MASK (3 << SSD1289_ENTRY_DMODE_SHIFT) -# define SSD1289_ENTRY_DMODE_RAM (0 << SSD1289_ENTRY_DMODE_SHIFT) -# define SSD1289_ENTRY_DMODE_GENERIC (1 << SSD1289_ENTRY_DMODE_SHIFT) -# define SSD1289_ENTRY_DMODE_RAMGEN (2 << SSD1289_ENTRY_DMODE_SHIFT) -# define SSD1289_ENTRY_DMODE_GENRAM (3 << SSD1289_ENTRY_DMODE_SHIFT) -#define SSD1289_ENTRY_WMODE (1 << 10) /* Select source of data in RAM */ -#define SSD1289_ENTRY_OEDEF (1 << 11) /* Define display window */ -#define SSD1289_ENTRY_TRANS (1 << 12) /* Transparent display */ -#define SSD1289_ENTRY_DFM_SHIFT (13) /* Color display mode */ -#define SSD1289_ENTRY_DFM_MASK (3 << SSD1289_ENTRY_DFM_SHIFT) -# define SSD1289_ENTRY_DFM_262K (2 << SSD1289_ENTRY_DFM_SHIFT) -# define SSD1289_ENTRY_DFM_65K (3 << SSD1289_ENTRY_DFM_SHIFT) -#define SSD1289_ENTRY_VSMODE (1 << 15) /* Frame frequency depends on VSYNC */ - -/* Generic Interface Control */ - -#define SSD1289_GIFCTRL_INVVS (1 << 0) /* Sets the signal polarity of DOTCLK pin */ -#define SSD1289_GIFCTRL_INVHS (1 << 1) /* Sets the signal polarity of DEN pin */ -#define SSD1289_GIFCTRL_NVDEN (1 << 2) /* Sets the signal polarity of HSYNC pin */ -#define SSD1289_GIFCTRL_INVDOT (1 << 3) /* Sets the signal polarity of VSYNC pin */ - -/* Horizontal Porch */ - -#define SSD1289_HPORCH_HBP_SHIFT (0) /* Set delay from falling edge of HSYNC signal to data */ -#define SSD1289_HPORCH_HBP_MASK (0xff << SSD1289_HPORCH_HBP_SHIFT) -#define SSD1289_HPORCH_XL_SHIFT (8) /* number of valid pixel per line */ -#define SSD1289_HPORCH_XL_MASK (0xff << SSD1289_HPORCH_XL_SHIFT) - -/* Vertical Porch */ - -#define SSD1289_VPORCH_VBP_SHIFT (0) /* Set delay from falling edge of VSYNC signal to line */ -#define SSD1289_VPORCH_VBP_MASK (0xff << SSD1289_VPORCH_VBP_SHIFT) -#define SSD1289_VPORCH_XFP_SHIFT (8) /* Delay from last line to falling edge of VSYNC of next frame */ -#define SSD1289_VPORCH_XFP_MASK (0xff << SSD1289_VPORCH_XFP_SHIFT) -#define SSD1289_VPORCH_ - -/* Power control 5 */ - -#define SSD1289_PWRCTRL5_VCM_SHIFT (0) /* Set the VcomH voltage */ -#define SSD1289_PWRCTRL5_VCM_MASK (0x3f << SSD1289_PWRCTRL5_VCM_SHIFT) -# define SSD1289_PWRCTRL5_VCM(n) ((n) << SSD1289_PWRCTRL5_VCM_SHIFT) -#define SSD1289_PWRCTRL5_NOTP (1 << 7) /* 1=VCM valid */ - -/* RAM write data mask 1 */ - -#define SSD1289_WRMASK1_WMG_SHIFT (2) -#define SSD1289_WRMASK1_WMG_MASK (0x3f << SSD1289_WRMASK1_WMG_SHIFT) -#define SSD1289_WRMASK1_WMR_SHIFT (10) -#define SSD1289_WRMASK1_WMR_MASK (0x3f << SSD1289_WRMASK1_WMR_SHIFT) - -#define SSD1289_WRMASK2_WMB_SHIFT (2) -#define SSD1289_WRMASK2_WMB_MASK (0x3f << SSD1289_WRMASK2_WMB_SHIFT) - -/* Frame Frequency */ - -#define SSD1289_FFREQ_OSC_SHIFT (12) /* Set the frame frequency */ -#define SSD1289_FFREQ_OSC_MASK (15 << SSD1289_FFREQ_OSC_SHIFT) -# define SSD1289_FFREQ_OSC_FF50 (0 << SSD1289_FFREQ_OSC_SHIFT) -# define SSD1289_FFREQ_OSC_FF55 (2 << SSD1289_FFREQ_OSC_SHIFT) -# define SSD1289_FFREQ_OSC_FF60 (5 << SSD1289_FFREQ_OSC_SHIFT) -# define SSD1289_FFREQ_OSC_FF65 (8 << SSD1289_FFREQ_OSC_SHIFT) -# define SSD1289_FFREQ_OSC_FF70 (10 << SSD1289_FFREQ_OSC_SHIFT) -# define SSD1289_FFREQ_OSC_FF75 (12 << SSD1289_FFREQ_OSC_SHIFT) -# define SSD1289_FFREQ_OSC_FF80 (14 << SSD1289_FFREQ_OSC_SHIFT) - -/* VCOM OTP */ - -#define SSD1289_VCOMOTP1_ACTIVATE 0x0006 -#define SSD1289_VCOMOTP1_FIRE 0x000a -#define SSD1289_VCOMOTP2_ACTIVATE 0x80c0 - -/* Optimize Access Speed 1, 2, 3 (omitted) */ - -/* Gamma control 1-10. Magic values. I won't try to represent the fields. */ - -/* Vertical scroll control 1 and 2 */ - -#define SSD1289_VSCROLL_MASK 0x1ff /* Scroll length */ - -/* Horizontal RAM address position */ - -#define SSD1289_HADDR_HSA_SHIFT (0) /* Window horizontal start address */ -#define SSD1289_HADDR_HSA_MASK (0xff << SSD1289_HADDR_HSA_SHIFT) -#define SSD1289_HADDR_HEA_SHIFT (8) /* Window horizontal end address */ -#define SSD1289_HADDR_HEA_MASK (0xff << SSD1289_HADDR_HEA_SHIFT) - -/* Vertical RAM address start/end position */ - -#define SSD1289_VSTART_MASK 0x1ff /* Window Vertical start address */ -#define SSD1289_VEND_MASK 0x1ff /* Window Vertical end address */ - -/* First window start/end */ - -#define SSD1289_W1START_MASK 0x1ff /* Start line for first screen */ -#define SSD1289_W1END_MASK 0x1ff /* End line for first screen */ - -/* Second window start/end */ - -#define SSD1289_W2START_MASK 0x1ff /* Start line for second screen */ -#define SSD1289_W2END_MASK 0x1ff /* End line for second screen */ - -/* Set GDDRAM X/Y address counter */ - -#define SSD1289_XADDR_MASK 0xff /* GDDRAM X address in the address counter */ -#define SSD1289_YADDR_MASK 0x1ff /* GDDRAM Y address in the address counter */ - -#endif /* CONFIG_LCD_SSD1289 */ -#endif /* __DRIVERS_LCD_SSD1289_H */ diff --git a/nuttx/drivers/lcd/ssd1305.h b/nuttx/drivers/lcd/ssd1305.h deleted file mode 100644 index 34678fa80..000000000 --- a/nuttx/drivers/lcd/ssd1305.h +++ /dev/null @@ -1,211 +0,0 @@ -/************************************************************************************** - * drivers/lcd/ssd1305.h - * Definitions for the Solomon Systech SSD1305 132x64 Dot Matrix OLED/PLED - * Segment/Common Driver with C - * - * Copyright (C) 2010 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt <gnutt@nuttx.org> - * - * References: SSD1305.pdf, "Solomon Systech SSD1305 132x64 Dot Matrix OLED/PLED - * Segment/Common Driver with Controller," Solomon Systech Limited, - * http://www.solomon-systech.com, May, 2008. - * - * 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 written 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. - * - **************************************************************************************/ - -#ifndef __DRIVERS_LCD_SSD1305_H -#define __DRIVERS_LCD_SSD1305_H - -/************************************************************************************** - * Included Files - **************************************************************************************/ - -/************************************************************************************** - * Pre-processor Definitions - **************************************************************************************/ -/* General Definitions ******************************************************/ - -#define SSD1305_COLORA 0 -#define SSD1305_COLORB 1 -#define SSD1305_COLORC 2 -#define SSD1305_COLORD 3 - -/* Fundamental Commands *****************************************************/ -#define SSD1305_SETCOLL 0x00 /* 0x00-0x0f: Set lower column address */ -# define SSD1305_COLL_MASK 0x0f -#define SSD1305_SETCOLH 0x10 /* 0x10-0x1f: Set higher column address */ -# define SSD1305_COLH_MASK 0x0f -#define SSD1305_ADDRMODE 0x20 /* 0x20: Set memory address mode */ -# define SSD1305_ADDRMODE_HOR 0x00 /* Data 1: Set horizontal address mode */ -# define SSD1305_ADDRMODE_VIRT 0x01 /* Data 1: Set virtal address mode */ -# define SSD1305_ADDRMODE_PAGE 0x02 /* Data 1: Set page address mode */ -#define SSD1305_SETCOLADDR 0x21 /* 0x21: Set column address */ - /* Data 1: Column start address: 0-131 */ - /* Data 2: Column end address: 0-131 */ -#define SSD1305_SETPAGEADDR 0x22 /* 0x22: Set page address */ - /* Data 1: Page start address: 0x00-0x7d */ - /* Data 2: Page end address: 0x00-0x7d */ -#define SSD1305_SETSTARTLINE 0x40 /* 0x40-7f: Set display start line */ -# define SSD1305_STARTLINE_MASK 0x3f - -#define SSD1305_SETCONTRAST 0x81 /* 0x81: Set contrast control */ - /* Data 1: Set 1 of 256 contrast steps */ -#define SSD1305_SETBRIGHTNESS 0x82 /* 0x82: Set brightness */ - /* Data 1: Set 1 of 256 contrast steps */ -#define SSD1305_SETLUT 0x91 /* 0x01: Set lookup table */ - /* Data 1: Pulse width: 31-63 */ - /* Data 2: Color A: 31-63 */ - /* Data 3: Color B: 31-63 */ - /* Data 4: Color C: 31-63 */ -#define SSD1305_SETBANKCOLOR1 0x92 /* 0x92: Set bank 1-16 color */ -# define SSD1305_SETBANK1(c) (c) /* Data 1, Bits 0-1: Bank 1 color */ -# define SSD1305_SETBANK2(c) (c << 2) /* Data 1, Bits 2-3: Bank 2 color */ -# define SSD1305_SETBANK3(c) (c << 4) /* Data 1, Bits 4-5: Bank 3 color */ -# define SSD1305_SETBANK4(c) (c << 6) /* Data 1, Bits 6-7: Bank 4 color */ -# define SSD1305_SETBANK5(c) (c) /* Data 2, Bits 0-1: Bank 5 color */ -# define SSD1305_SETBANK6(c) (c << 2) /* Data 2, Bits 2-3: Bank 6 color */ -# define SSD1305_SETBANK7(c) (c << 4) /* Data 2, Bits 4-5: Bank 7 color */ -# define SSD1305_SETBANK8(c) (c << 6) /* Data 2, Bits 6-7: Bank 8 color */ -# define SSD1305_SETBANK9(c) (c) /* Data 3, Bits 0-1: Bank 9 color */ -# define SSD1305_SETBANK10(c) (c << 2) /* Data 3, Bits 2-3: Bank 10 color */ -# define SSD1305_SETBANK11(c) (c << 4) /* Data 3, Bits 4-5: Bank 11 color */ -# define SSD1305_SETBANK12(c) (c << 6) /* Data 3, Bits 6-7: Bank 12 color */ -# define SSD1305_SETBANK13(c) (c) /* Data 4, Bits 0-1: Bank 13 color */ -# define SSD1305_SETBANK14(c) (c << 2) /* Data 4, Bits 2-3: Bank 14 color */ -# define SSD1305_SETBANK15(c) (c << 4) /* Data 4, Bits 4-5: Bank 15 color */ -# define SSD1305_SETBANK16(c) (c << 6) /* Data 4, Bits 6-7: Bank 16 color */ -#define SSD1305_SETBANKCOLOR2 0x93 /* 0x93: Set bank 17-32 color */ -# define SSD1305_SETBANK17(c) (c) /* Data 1, Bits 0-1: Bank 17 color */ -# define SSD1305_SETBANK18(c) (c << 2) /* Data 1, Bits 2-3: Bank 18 color */ -# define SSD1305_SETBANK19(c) (c << 4) /* Data 1, Bits 4-5: Bank 19 color */ -# define SSD1305_SETBANK20(c) (c << 6) /* Data 1, Bits 6-7: Bank 20 color */ -# define SSD1305_SETBANK21(c) (c) /* Data 2, Bits 0-1: Bank 21 color */ -# define SSD1305_SETBANK22(c) (c << 2) /* Data 2, Bits 2-3: Bank 22 color */ -# define SSD1305_SETBANK23(c) (c << 4) /* Data 2, Bits 4-5: Bank 23 color */ -# define SSD1305_SETBANK24(c) (c << 6) /* Data 2, Bits 6-7: Bank 24 color */ -# define SSD1305_SETBANK25(c) (c) /* Data 3, Bits 0-1: Bank 25 color */ -# define SSD1305_SETBANK26(c) (c << 2) /* Data 3, Bits 2-3: Bank 26 color */ -# define SSD1305_SETBANK27(c) (c << 4) /* Data 3, Bits 4-5: Bank 27 color */ -# define SSD1305_SETBANK28(c) (c << 6) /* Data 3, Bits 6-7: Bank 28 color */ -# define SSD1305_SETBANK29(c) (c) /* Data 4, Bits 0-1: Bank 29 color */ -# define SSD1305_SETBANK30(c) (c << 2) /* Data 4, Bits 2-3: Bank 30 color */ -# define SSD1305_SETBANK31(c) (c << 4) /* Data 4, Bits 4-5: Bank 31 color */ -# define SSD1305_SETBANK32(c) (c << 6) /* Data 4, Bits 6-7: Bank 32 color */ -#define SSD1305_MAPCOL0 0xa0 /* 0xa0: Column address 0 is mapped to SEG0 */ -#define SSD1305_MAPCOL131 0xa1 /* 0xa1: Column address 131 is mapped to SEG0 */ -#define SSD1305_DISPRAM 0xa4 /* 0xa4: Resume to RAM content display */ -#define SSD1305_DISPENTIRE 0xa5 /* 0xa5: Entire display ON */ -#define SSD1305_DISPNORMAL 0xa6 /* 0xa6: Normal display */ -#define SSD1305_DISPINVERTED 0xa7 /* 0xa7: Inverse display */ - -#define SSD1305_SETMUX 0xa8 /* 0xa8: Set Multiplex Ratio*/ - /* Data 1: MUX ratio -1: 15-63 */ -#define SSD1305_DIMMODE 0xab /* 0xab: Dim mode setting */ - /* Data 1: Reserverd, must be zero */ - /* Data 2: Contrast for bank1: 0-255 */ - /* Data 3: Brightness for color bank: 0-255 */ -#define SSD1305_MSTRCONFIG 0xad /* 0xad: Master configuration */ -# define SSD1305_MSTRCONFIG_EXTVCC 0x8e /* Data 1: Select external Vcc */ -#define SSD1305_DISPONDIM 0xac /* 0xac: Display ON in dim mode */ -#define SSD1305_DISPOFF 0xae /* 0xae: Display OFF (sleep mode) */ -#define SSD1305_DISPON 0xaf /* 0xaf: Display ON in normal mode */ -#define SSD1305_SETPAGESTART 0xb0 /* 0xb0-b7: Set page start address */ -# define SSD1305_PAGESTART_MASK 0x07 -#define SSD1305_SETCOMNORMAL 0xc0 /* 0xc0: Set COM output, normal mode */ -#define SSD1305_SETCOMREMAPPED 0xc8 /* 0xc8: Set COM output, remapped mode */ - -#define SSD1305_SETOFFSET 0xd3 /* 0xd3: Set display offset */ - /* Data 1: Vertical shift by COM: 0-63 */ -#define SSD1305_SETDCLK 0xd5 /* 0xd5: Set display clock divide ratio/oscillator */ -# define SSD1305_DCLKDIV_SHIFT (0) /* Data 1, Bits 0-3: DCLK divide ratio/frequency*/ -# define SSD1305_DCLKDIV_MASK 0x0f -# define SSD1305_DCLKFREQ_SHIFT (4) /* Data 1, Bits 4-7: DCLK divide oscillator frequency */ -# define SSD1305_DCLKFREQ_MASK 0xf0 -#define SSD1305_SETCOLORMODE 0xd8 /* 0xd: Set area color and low power display modes */ -# define SSD1305_COLORMODE_MONO 0x00 /* Data 1, Bits 4-5: 00=monochrome */ -# define SSD1305_COLORMODE_COLOR 0x30 /* Data 1, Bits 4-5: 11=area color enable */ -# define SSD1305_POWERMODE_NORMAL 0x00 /* Data 1, Bits 0,2: 00=normal power mode */ -# define SSD1305_POWERMODE_LOW 0x05 /* Data 1, Bits 0,2: 11=low power display mode */ -#define SSD1305_SETPRECHARGE 0xd9 /* 0xd9: Set pre-charge period */ -# define SSD1305_PHASE1_SHIFT (0) /* Data 1, Bits 0-3: Phase 1 period of up to 15 DCLK clocks */ -# define SSD1305_PHASE1_MASK 0x0f -# define SSD1305_PHASE2_SHIFT (4) /* Data 1, Bits 4-7: Phase 2 period of up to 15 DCLK clocks */ -# define SSD1305_PHASE2_MASK 0xf0 -#define SSD1305_SETCOMCONFIG 0xda /* 0xda: Set COM configuration */ -# define SSD1305_COMCONFIG_SEQ 0x02 /* Data 1, Bit 4: 0=Sequential COM pin configuration */ -# define SSD1305_COMCONFIG_ALT 0x12 /* Data 1, Bit 4: 1=Alternative COM pin configuration */ -# define SSD1305_COMCONFIG_NOREMAP 0x02 /* Data 1, Bit 5: 0=Disable COM Left/Right remap */ -# define SSD1305_COMCONFIG_REMAP 0x22 /* Data 1, Bit 5: 1=Enable COM Left/Right remap */ -#define SSD1305_SETVCOMHDESEL 0xdb /* 0xdb: Set VCOMH delselect level */ -# define SSD1305_VCOMH_x4p3 0x00 /* Data 1: ~0.43 x Vcc */ -# define SSD1305_VCOMH_x7p7 0x34 /* Data 1: ~0.77 x Vcc */ -# define SSD1305_VCOMH_x8p3 0x3c /* Data 1: ~0.83 x Vcc */ -#define SSD1305_ENTER_RMWMODE 0xe0 /* 0xe0: Enter the Read Modify Write mode */ -#define SSD1305_NOP 0xe3 /* 0xe3: NOP Command for no operation */ -#define SSD1305_EXIT_RMWMODE 0xee /* 0xee: Leave the Read Modify Write mode */ - -/* Graphic Acceleration Commands ********************************************/ - -#define SSD1305_HSCROLL_RIGHT 0x26 /* 0x26: Right horizontal scroll */ -#define SSD1305_HSCROLL_LEFT 0x27 /* 0x27: Left horizontal scroll */ - /* Data 1, Bits 0-2: Column scroll offset: 0-4 */ - /* Data 2, Bits 0-2: Start page address: 0-7 */ -#define SSD1305_HSCROLL_FRAMES6 0x00 /* Data 3, Bits 0-2: Timer interval, 000=6 frames */ -#define SSD1305_HSCROLL_FRAMES32 0x01 /* Data 3, Bits 0-2: Timer interval, 001=32 frames */ -#define SSD1305_HSCROLL_FRAMES64 0x02 /* Data 3, Bits 0-2: Timer interval, 010=64 frames */ -#define SSD1305_HSCROLL_FRAMES128 0x03 /* Data 3, Bits 0-2: Timer interval, 011=128 frames */ -#define SSD1305_HSCROLL_FRAMES3 0x04 /* Data 3, Bits 0-2: Timer interval, 100=3 frames */ -#define SSD1305_HSCROLL_FRAMES4 0x05 /* Data 3, Bits 0-2: Timer interval, 101=4 frames */ -#define SSD1305_HSCROLL_FRAMES2 0x06 /* Data 3, Bits 0-2: Timer interval, 110=2 frames */ - /* Data 4, Bits 0-2: End page address: 0-7 */ - -#define SSD1305_VSCROLL_RIGHT 0x29 /* 0x26: Vertical and right horizontal scroll */ -#define SSD1305_VSCROLL_LEFT 0x2a /* 0x27: Vertical and left horizontal scroll */ - /* Data 1, Bits 0-2: Column scroll offset: 0-4 */ - /* Data 2, Bits 0-2: Start page address: 0-7 */ -#define SSD1305_VSCROLL_FRAMES6 0x00 /* Data 3, Bits 0-2: Timer interval, 000=6 frames */ -#define SSD1305_VSCROLL_FRAMES32 0x01 /* Data 3, Bits 0-2: Timer interval, 001=32 frames */ -#define SSD1305_VSCROLL_FRAMES64 0x02 /* Data 3, Bits 0-2: Timer interval, 010=64 frames */ -#define SSD1305_VSCROLL_FRAMES128 0x03 /* Data 3, Bits 0-2: Timer interval, 011=128 frames */ -#define SSD1305_VSCROLL_FRAMES3 0x04 /* Data 3, Bits 0-2: Timer interval, 100=3 frames */ -#define SSD1305_VSCROLL_FRAMES4 0x05 /* Data 3, Bits 0-2: Timer interval, 101=4 frames */ -#define SSD1305_VSCROLL_FRAMES2 0x06 /* Data 3, Bits 0-2: Timer interval, 110=2 frames */ - /* Data 4, Bits 0-2: End page address: 0-7 */ - /* Data 5, Bits 0-5: Vertical scrolling offset: 0-63 */ -#define SSD1305_SCROLL_STOP 0x2e /* 0x2e: Deactivate scroll */ -#define SSD1305_SCROLL_START 0x2f /* 0x2f: Activate scroll */ -#define SSD1305_VSCROLL_AREA 0xa3 /* 0xa3: Set vertical scroll area */ - /* Data 1: Number of rows in the top fixed area */ - /* Data 1: Number of rows in the scroll area */ - -/* Status register bit definitions ******************************************/ - -#define SSD1305_STATUS_DISPOFF (1 << 6) /* Bit 6: 1=Display off */ - -#endif /* __DRIVERS_LCD_SSD1305_H */ diff --git a/nuttx/drivers/lcd/ug-2864ambag01.c b/nuttx/drivers/lcd/ug-2864ambag01.c deleted file mode 100644 index 6b3d6d5a8..000000000 --- a/nuttx/drivers/lcd/ug-2864ambag01.c +++ /dev/null @@ -1,1161 +0,0 @@ -/************************************************************************************** - * drivers/lcd/ug-2864ambag01.c - * Driver for Univision UG-2864AMBAG01 OLED display (wih SH1101A controller) in SPI - * mode - * - * Copyright (C) 2012 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt <gnutt@nuttx.org> - * - * References: - * 1. Product Specification (Preliminary), Part Name: OEL Display Module, Part ID: - * UG-2864AMBAG01, Doc No: SASI-9015-A, Univision Technology Inc. - * 2. SH1101A, 132 X 64 Dot Matrix OLED/PLED, Preliminary Segment/Common Driver with - * Controller, Sino Wealth - * - * 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 written 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. - * - **************************************************************************************/ -/************************************************************************************** - * Device memory organization: - * - * +----------------------------+ - * | Column | - * --------+----+---+---+---+-...-+-----+ - * Page | 0 | 1 | 2 | 3 | ... | 131 | - * --------+----+---+---+---+-...-+-----+ - * Page 0 | D0 | X | | | | | - * | D1 | X | | | | | - * | D2 | X | | | | | - * | D3 | X | | | | | - * | D4 | X | | | | | - * | D5 | X | | | | | - * | D6 | X | | | | | - * | D7 | X | | | | | - * --------+----+---+---+---+-...-+-----+ - * Page 1 | | | | | | | - * --------+----+---+---+---+-...-+-----+ - * Page 2 | | | | | | | - * --------+----+---+---+---+-...-+-----+ - * Page 3 | | | | | | | - * --------+----+---+---+---+-...-+-----+ - * Page 4 | | | | | | | - * --------+----+---+---+---+-...-+-----+ - * Page 5 | | | | | | | - * --------+----+---+---+---+-...-+-----+ - * Page 6 | | | | | | | - * --------+----+---+---+---+-...-+-----+ - * Page 7 | | | | | | | - * --------+----+---+---+---+-...-+-----+ - * - * -----------------------------------+--------------------------------------- - * Landscape Display: | Reverse Landscape Display: - * --------+-----------------------+ | --------+---------------------------+ - * | Column | | | Column | - * --------+---+---+---+-...-+-----+ | --------+-----+-----+-----+-...-+---+ - * Page 0 | 0 | 1 | 2 | | 131 | | Page 7 | 131 | 130 | 129 | | 0 | - * --------+---+---+---+-...-+-----+ | --------+-----+-----+-----+-...-+---+ - * Page 1 | V | | Page 6 | ^ | - * --------+---+---+---+-...-+-----+ | --------+-----+-----+-----+-...-+---+ - * Page 2 | V | | Page 5 | ^ | - * --------+---+---+---+-...-+-----+ | --------+-----+-----+-----+-...-+---+ - * Page 3 | V | | Page 4 | ^ | - * --------+---+---+---+-...-+-----+ | --------+-----+-----+-----+-...-+---+ - * Page 4 | V | | Page 3 | ^ | - * --------+---+---+---+-...-+-----+ | --------+-----+-----+-----+-...-+---+ - * Page 5 | V | | Page 2 | ^ | - * --------+---+---+---+-...-+-----+ | --------+-----+-----+-----+-...-+---+ - * Page 6 | V | | Page 1 | ^ | - * --------+---+---+---+-...-+-----+ | --------+-----+-----+-----+-...-+---+ - * Page 7 | V | | Page 0 | ^ | - * --------+---+---+---+-...-+-----+ | --------+-----+-----+-----+-...-+---+ - * -----------------------------------+--------------------------------------- - * - * -----------------------------------+--------------------------------------- - * Portrait Display: | Reverse Portrait Display: - * -----------+---------------------+ | -----------+---------------------+ - * | Page | | | Page | - * -----------+---+---+---+-...-+---+ | -----------+---+---+---+-...-+---+ - * Column 0 | 0 | 1 | 2 | | 7 | | Column 131 | 7 | 6 | 5 | | 0 | - * -----------+---+---+---+-...-+---+ | -----------+---+---+---+-...-+---+ - * Column 1 | > > > > > | | Column 130 | | - * -----------+---+---+---+-...-+---+ | -----------+---+---+---+-...-+---+ - * Column 2 | | | Column 129 | | - * -----------+---+---+---+-...-+---+ | -----------+---+---+---+-...-+---+ - * ... | | | ... | | - * -----------+---+---+---+-...-+---+ | -----------+---+---+---+-...-+---+ - * Column 131 | | | Column 0 | < < < < < | - * -----------+---+---+---+-...-+---+ | -----------+---+---+---+-...-+---+ - * -----------------------------------+---------------------------------------- - **************************************************************************************/ - -/************************************************************************************** - * Included Files - **************************************************************************************/ - -#include <nuttx/config.h> - -#include <sys/types.h> -#include <stdint.h> -#include <stdbool.h> -#include <string.h> -#include <errno.h> -#include <debug.h> - -#include <nuttx/arch.h> -#include <nuttx/spi.h> -#include <nuttx/lcd/lcd.h> -#include <nuttx/lcd/ug-2864ambag01.h> - -#include <arch/irq.h> - -#ifdef CONFIG_LCD_UG2864AMBAG01 - -/************************************************************************************** - * Pre-processor Definitions - **************************************************************************************/ -/* Configuration **********************************************************************/ -/* Limitations of the current configuration that I hope to fix someday */ - -#if CONFIG_UG2864AMBAG01_NINTERFACES != 1 -# warning "This implementation supports only a single OLED device" -# undef CONFIG_UG2864AMBAG01_NINTERFACES -# define CONFIG_UG2864AMBAG01_NINTERFACES 1 -#endif - -#if defined(CONFIG_LCD_PORTRAIT) || defined(CONFIG_LCD_RPORTRAIT) -# warning "No support yet for portrait modes" -# define CONFIG_LCD_LANDSCAPE 1 -# undef CONFIG_LCD_PORTRAIT -# undef CONFIG_LCD_RLANDSCAPE -# undef CONFIG_LCD_RPORTRAIT -#elif defined(CONFIG_LCD_RLANDSCAPE) -# warning "Reverse landscape mode is untested and, hence, probably buggy" -#endif - -/* SH1101A Commands *******************************************************************/ - -#define SH1101A_SETCOLL(ad) (0x00 | ((ad) & 0x0f)) /* Set Lower Column Address: (00h - 0fh) */ -#define SH1101A_SETCOLH(ad) (0x10 | ((ad) & 0x0f)) /* Set Higher Column Address: (10h - 1fh) */ -#define SH1101A_STARTLINE(ln) (0x40 | ((ln) & 0x3f)) /* Set Display Start Line: (40h - 7fh) */ -#define SH1101A_CONTRAST_MODE (0x81) /* Set Contrast Control Register: (Double Bytes Command) */ -# define SH1101A_CONTRAST(c) (c) -#define SH1101A_SEGREMAP(m) (0xa0 | ((m) & 0x01)) /* Set Segment Re-map: (a0h - a1h) */ -# define SH1101A_REMAPRIGHT SH1101A_SEGREMAP(0) /* Right rotation */ -# define SH1101A_REMAPPLEFT SH1101A_SEGREMAP(1) /* Left rotation */ -#define SH1101A_EDISPOFFON(s) (0xa4 | ((s) & 0x01)) /* Set Entire Display OFF/ON: (a4h - a5h) */ -# define SH1101A_EDISPOFF SH1101A_EDISPOFFON(0) /* Display off */ -# define SH1101A_EDISPON SH1101A_EDISPOFFON(1) /* Display on */ -#define SH1101A_NORMREV(s) (0xa6 | ((s) & 0x01)) /* Set Normal/Reverse Display: (a6h -a7h) */ -# define SH1101A_NORMAL SH1101A_NORMREV(0) /* Normal display */ -# define SH1101A_REVERSE SH1101A_NORMREV(1) /* Reverse display */ -#define SH1101A_MRATIO_MODE (0xa8) /* Set Multiplex Ration: (Double Bytes Command) */ -# define SH1101A_MRATIO(d) ((d) & 0x3f) -#define SH1101A_DCDC_MODE (0xad) /* Set DC-DC OFF/ON: (Double Bytes Command) */ -# define SH1101A_DCDC_OFF (0x8a) - # define SH1101A_DCDC_ON (0x8b) -#define SH1101A_DISPOFFON(s) (0xae | ((s) & 0x01)) /* Display OFF/ON: (aeh - afh) */ -# define SH1101A_DISPOFF SH1101A_DISPOFFON(0) /* Display off */ -# define SH1101A_DISPON SH1101A_DISPOFFON(1) /* Display on */ -#define SH1101A_PAGEADDR(a) (0xb0 | ((a) & 0x0f)) /* Set Page Address: (b0h - b7h) */ -#define SH1101A_SCANDIR(d) (0xc0 | ((d) & 0x08)) /* Set Common Output Scan Direction: (c0h - c8h) */ -# define SH1101A_SCANFROMCOM0 SH1101A_SCANDIR(0x00) /* Scan from COM[0] to COM[n-1]*/ -# define SH1101A_SCANTOCOM0 SH1101A_SCANDIR(0x08) /* Scan from COM[n-1] to COM[0] */ -#define SH1101A_DISPOFFS_MODE (0xd3) /* Set Display Offset: (Double Bytes Command) */ -# define SH1101A_DISPOFFS(o) ((o) & 0x3f) -#define SH1101A_CLKDIV_SET (0xd5) /* Set Display Clock Divide Ratio/Oscillator Frequency: (Double Bytes Command) */ -# define SH1101A_CLKDIV(f,d) ((((f) & 0x0f) << 4) | ((d) & 0x0f)) -#define SH1101A_CHRGPER_SET (0xd9) /* Set Dis-charge/Pre-charge Period: (Double Bytes Command) */ -# define SH1101A_CHRGPER(d,p) ((((d) & 0x0f) << 4) | ((p) & 0x0f)) -#define SH1101A_CMNPAD_CONFIG (0xda) /* Set Common pads hardware configuration: (Double Bytes Command) */ - #define SH1101A_CMNPAD(c) ((0x02) | ((c) & 0x10)) -#define SH1101A_VCOM_SET (0xdb) /* Set VCOM Deselect Level: (Double Bytes Command) */ -# define SH1101A_VCOM(v) (v) -#define SH1101A_RMWSTART (0xe0) /* Read-Modify-Write: (e0h) */ -#define SH1101A_NOP (0xe3) /* NOP: (e3h) */ -#define SH1101A_END (0xee) /* End: (eeh) */ - -#define SH1101A_WRDATA(d) (d) /* Write Display Data */ -#define SH1101A_STATUS_BUSY (0x80) /* Read Status */ -#define SH1101A_STATUS_ONOFF (0x40) -#define SH1101A_RDDATA(d) (d) /* Read Display Data */ - -/* Color Properties *******************************************************************/ -/* Display Resolution - * - * The SH1101A display controller can handle a resolution of 132x64. The UG-2864AMBAG01 - * on the base board is 128x64. - */ - -#define UG2864AMBAG01_DEV_XRES 128 /* Only 128 of 131 columns used */ -#define UG2864AMBAG01_DEV_YRES 64 /* 8 pages each 8 rows */ -#define UG2864AMBAG01_DEV_XOFFSET 2 /* Offset to logical column 0 */ -#define UG2864AMBAG01_DEV_PAGES 8 /* 8 pages */ - -#if defined(CONFIG_LCD_LANDSCAPE) || defined(CONFIG_LCD_RLANDSCAPE) -# define UG2864AMBAG01_XRES UG2864AMBAG01_DEV_XRES -# define UG2864AMBAG01_YRES UG2864AMBAG01_DEV_YRES -#else -# define UG2864AMBAG01_XRES UG2864AMBAG01_DEV_YRES -# define UG2864AMBAG01_YRES UG2864AMBAG01_DEV_XRES -#endif - -/* Color depth and format */ - -#define UG2864AMBAG01_BPP 1 -#define UG2864AMBAG01_COLORFMT FB_FMT_Y1 - -/* Bytes per logical row and actual device row */ - -#define UG2864AMBAG01_XSTRIDE (UG2864AMBAG01_XRES >> 3) -#define UG2864AMBAG01_YSTRIDE (UG2864AMBAG01_YRES >> 3) - -/* Default contrast */ - -#define UG2864AMBAG01_CONTRAST (128) - -/* The size of the shadow frame buffer or one row buffer. - * - * Frame buffer size: 128 columns x 64 rows / 8 bits-per-pixel - * Row size: 128 columns x 8 rows-per-page / 8 bits-per-pixel - */ - -#define UG2864AMBAG01_FBSIZE (UG2864AMBAG01_XSTRIDE * UG2864AMBAG01_YRES) -#define UG2864AMBAG01_ROWSIZE (UG2864AMBAG01_XSTRIDE) - -/* Bit helpers */ - -#define LS_BIT (1 << 0) -#define MS_BIT (1 << 7) - -/* Debug ******************************************************************************/ - -#ifdef CONFIG_DEBUG_LCD -# define lcddbg(format, arg...) dbg(format, ##arg) -# define lcdvdbg(format, arg...) vdbg(format, ##arg) -#else -# define lcddbg(x...) -# define lcdvdbg(x...) -#endif - -/************************************************************************************** - * Private Type Definition - **************************************************************************************/ - -/* This structure describes the state of this driver */ - -struct ug2864ambag01_dev_s -{ - struct lcd_dev_s dev; /* Publically visible device structure */ - - /* Private LCD-specific information follows */ - - FAR struct spi_dev_s *spi; /* Cached SPI device reference */ - uint8_t contrast; /* Current contrast setting */ - bool on; /* true: display is on */ - - - /* The SH1101A does not support reading from the display memory in SPI mode. - * Since there is 1 BPP and access is byte-by-byte, it is necessary to keep - * a shadow copy of the framebuffer memory. At 128x64, this amounts to 1KB. - */ - - uint8_t fb[UG2864AMBAG01_FBSIZE]; -}; - -/************************************************************************************** - * Private Function Protototypes - **************************************************************************************/ - -/* Low-level SPI helpers */ - -#ifdef CONFIG_SPI_OWNBUS -static inline void ug2864ambag01_configspi(FAR struct spi_dev_s *spi); -# define ug2864ambag01_lock(spi) -# define ug2864ambag01_unlock(spi) -#else -# define ug2864ambag01_configspi(spi) -static void ug2864ambag01_lock(FAR struct spi_dev_s *spi); -static void ug2864ambag01_unlock(FAR struct spi_dev_s *spi); -#endif - -/* LCD Data Transfer Methods */ - -static int ug2864ambag01_putrun(fb_coord_t row, fb_coord_t col, - FAR const uint8_t *buffer, size_t npixels); -static int ug2864ambag01_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer, - size_t npixels); - -/* LCD Configuration */ - -static int ug2864ambag01_getvideoinfo(FAR struct lcd_dev_s *dev, - FAR struct fb_videoinfo_s *vinfo); -static int ug2864ambag01_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planeno, - FAR struct lcd_planeinfo_s *pinfo); - -/* LCD RGB Mapping */ - -#ifdef CONFIG_FB_CMAP -# error "RGB color mapping not supported by this driver" -#endif - -/* Cursor Controls */ - -#ifdef CONFIG_FB_HWCURSOR -# error "Cursor control not supported by this driver" -#endif - -/* LCD Specific Controls */ - -static int ug2864ambag01_getpower(struct lcd_dev_s *dev); -static int ug2864ambag01_setpower(struct lcd_dev_s *dev, int power); -static int ug2864ambag01_getcontrast(struct lcd_dev_s *dev); -static int ug2864ambag01_setcontrast(struct lcd_dev_s *dev, unsigned int contrast); - -/************************************************************************************** - * Private Data - **************************************************************************************/ - -/* This is working memory allocated by the LCD driver for each LCD device - * and for each color plane. This memory will hold one raster line of data. - * The size of the allocated run buffer must therefore be at least - * (bpp * xres / 8). Actual alignment of the buffer must conform to the - * bitwidth of the underlying pixel type. - * - * If there are multiple planes, they may share the same working buffer - * because different planes will not be operate on concurrently. However, - * if there are multiple LCD devices, they must each have unique run buffers. - */ - -static uint8_t g_runbuffer[UG2864AMBAG01_ROWSIZE]; - -/* This structure describes the overall LCD video controller */ - -static const struct fb_videoinfo_s g_videoinfo = -{ - .fmt = UG2864AMBAG01_COLORFMT, /* Color format: RGB16-565: RRRR RGGG GGGB BBBB */ - .xres = UG2864AMBAG01_XRES, /* Horizontal resolution in pixel columns */ - .yres = UG2864AMBAG01_YRES, /* Vertical resolution in pixel rows */ - .nplanes = 1, /* Number of color planes supported */ -}; - -/* This is the standard, NuttX Plane information object */ - -static const struct lcd_planeinfo_s g_planeinfo = -{ - .putrun = ug2864ambag01_putrun, /* Put a run into LCD memory */ - .getrun = ug2864ambag01_getrun, /* Get a run from LCD memory */ - .buffer = (uint8_t*)g_runbuffer, /* Run scratch buffer */ - .bpp = UG2864AMBAG01_BPP, /* Bits-per-pixel */ -}; - -/* This is the OLED driver instance (only a single device is supported for now) */ - -static struct ug2864ambag01_dev_s g_oleddev = -{ - .dev = - { - /* LCD Configuration */ - - .getvideoinfo = ug2864ambag01_getvideoinfo, - .getplaneinfo = ug2864ambag01_getplaneinfo, - - /* LCD RGB Mapping -- Not supported */ - /* Cursor Controls -- Not supported */ - - /* LCD Specific Controls */ - - .getpower = ug2864ambag01_getpower, - .setpower = ug2864ambag01_setpower, - .getcontrast = ug2864ambag01_getcontrast, - .setcontrast = ug2864ambag01_setcontrast, - }, -}; - -/************************************************************************************** - * Private Functions - **************************************************************************************/ - -/************************************************************************************** - * Name: ug2864ambag01_configspi - * - * Description: - * Configure the SPI for use with the UG-2864AMBAG01 - * - * Input Parameters: - * spi - Reference to the SPI driver structure - * - * Returned Value: - * None - * - * Assumptions: - * - **************************************************************************************/ - -#ifdef CONFIG_SPI_OWNBUS -static inline void ug2864ambag01_configspi(FAR struct spi_dev_s *spi) -{ - lcdvdbg("Mode: %d Bits: 8 Frequency: %d\n", - CONFIG_UG2864AMBAG01_SPIMODE, CONFIG_UG2864AMBAG01_FREQUENCY); - - /* Configure SPI for the UG-2864AMBAG01. But only if we own the SPI bus. Otherwise, - * don't bother because it might change. - */ - - SPI_SETMODE(spi, CONFIG_UG2864AMBAG01_SPIMODE); - SPI_SETBITS(spi, 8); - SPI_SETFREQUENCY(spi, CONFIG_UG2864AMBAG01_FREQUENCY); -} -#endif - -/************************************************************************************** - * Name: ug2864ambag01_lock - * - * Description: - * Select the SPI, locking and re-configuring if necessary - * - * Input Parameters: - * spi - Reference to the SPI driver structure - * - * Returned Value: - * None - * - * Assumptions: - * - **************************************************************************************/ - -#ifndef CONFIG_SPI_OWNBUS -static inline void ug2864ambag01_lock(FAR struct spi_dev_s *spi) -{ - /* Lock the SPI bus if there are multiple devices competing for the SPI bus. */ - - SPI_LOCK(spi, true); - - /* Now make sure that the SPI bus is configured for the UG-2864AMBAG01 (it - * might have gotten configured for a different device while unlocked) - */ - - SPI_SETMODE(spi, CONFIG_UG2864AMBAG01_SPIMODE); - SPI_SETBITS(spi, 8); - SPI_SETFREQUENCY(spi, CONFIG_UG2864AMBAG01_FREQUENCY); -} -#endif - -/************************************************************************************** - * Name: ug2864ambag01_unlock - * - * Description: - * De-select the SPI - * - * Input Parameters: - * spi - Reference to the SPI driver structure - * - * Returned Value: - * None - * - * Assumptions: - * - **************************************************************************************/ - -#ifndef CONFIG_SPI_OWNBUS -static inline void ug2864ambag01_unlock(FAR struct spi_dev_s *spi) -{ - /* De-select UG-2864AMBAG01 chip and relinquish the SPI bus. */ - - SPI_LOCK(spi, false); -} -#endif - -/************************************************************************************** - * Name: ug2864ambag01_putrun - * - * Description: - * This method can be used to write a partial raster line to the LCD. - * - * Input Parameters: - * row - Starting row to write to (range: 0 <= row < yres) - * col - Starting column to write to (range: 0 <= col <= xres-npixels) - * buffer - The buffer containing the run to be written to the LCD - * npixels - The number of pixels to write to the LCD - * (range: 0 < npixels <= xres-col) - * - **************************************************************************************/ - -#if defined(CONFIG_LCD_LANDSCAPE) || defined(CONFIG_LCD_RLANDSCAPE) -static int ug2864ambag01_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer, - size_t npixels) -{ - /* Because of this line of code, we will only be able to support a single UG device */ - - FAR struct ug2864ambag01_dev_s *priv = (FAR struct ug2864ambag01_dev_s *)&g_oleddev; - FAR uint8_t *fbptr; - FAR uint8_t *ptr; - uint8_t devcol; - uint8_t fbmask; - uint8_t page; - uint8_t usrmask; - int pixlen; - uint8_t i; - - lcdvdbg("row: %d col: %d npixels: %d\n", row, col, npixels); - DEBUGASSERT(buffer); - - /* Clip the run to the display */ - - pixlen = npixels; - if ((unsigned int)col + (unsigned int)pixlen > (unsigned int)UG2864AMBAG01_XRES) - { - pixlen = (int)UG2864AMBAG01_XRES - (int)col; - } - - /* Verify that some portion of the run remains on the display */ - - if (pixlen <= 0 || row > UG2864AMBAG01_YRES) - { - return OK; - } - - /* Perform coordinate conversion for reverse landscape mode */ - -#ifdef CONFIG_LCD_RLANDSCAPE - row = (UG2864AMBAG01_YRES-1) - row; - col = (UG2864AMBAG01_XRES-1) - col; -#endif - - /* Get the page number. The range of 64 lines is divided up into eight - * pages of 8 lines each. - */ - - page = row >> 3; - - /* Update the shadow frame buffer memory. First determine the pixel - * position in the frame buffer memory. Pixels are organized like - * this: - * - * --------+---+---+---+---+-...-+-----+ - * Segment | 0 | 1 | 2 | 3 | ... | 131 | - * --------+---+---+---+---+-...-+-----+ - * D0 | | X | | | | | - * D1 | | X | | | | | - * D2 | | X | | | | | - * D3 | | X | | | | | - * D4 | | X | | | | | - * D5 | | X | | | | | - * D6 | | X | | | | | - * D7 | | X | | | | | - * --------+---+---+---+---+-...-+-----+ - * - * So, in order to draw a white, horizontal line, at row 45. we - * would have to modify all of the bytes in page 45/8 = 5. We - * would have to set bit 45%8 = 5 in every byte in the page. - */ - - fbmask = 1 << (row & 7); - fbptr = &priv->fb[page * UG2864AMBAG01_XRES + col]; -#ifdef CONFIG_LCD_RLANDSCAPE - ptr = fbptr + pixlen - 1; -#else - ptr = fbptr; -#endif -#ifdef CONFIG_NX_PACKEDMSFIRST - usrmask = MS_BIT; -#else - usrmask = LS_BIT; -#endif - - for (i = 0; i < pixlen; i++) - { - /* Set or clear the corresponding bit */ - -#ifdef CONFIG_LCD_RLANDSCAPE - if ((*buffer & usrmask) != 0) - { - *ptr-- |= fbmask; - } - else - { - *ptr-- &= ~fbmask; - } -#else - if ((*buffer & usrmask) != 0) - { - *ptr++ |= fbmask; - } - else - { - *ptr++ &= ~fbmask; - } -#endif - - /* Inc/Decrement to the next source pixel */ - -#ifdef CONFIG_NX_PACKEDMSFIRST - if (usrmask == LS_BIT) - { - buffer++; - usrmask = MS_BIT; - } - else - { - usrmask >>= 1; - } -#else - if (usrmask == MS_BIT) - { - buffer++; - usrmask = LS_BIT; - } - else - { - usrmask <<= 1; - } -#endif - } - - /* Offset the column position to account for smaller horizontal - * display range. - */ - - devcol = col + UG2864AMBAG01_DEV_XOFFSET; - - /* Lock and select device */ - - ug2864ambag01_lock(priv->spi); - SPI_SELECT(priv->spi, SPIDEV_DISPLAY, true); - - /* Select command transfer */ - - SPI_CMDDATA(priv->spi, SPIDEV_DISPLAY, true); - - /* Set the starting position for the run */ - /* Set the column address to the XOFFSET value */ - - SPI_SEND(priv->spi, SH1101A_SETCOLL(devcol & 0x0f)); - SPI_SEND(priv->spi, SH1101A_SETCOLH(devcol >> 4)); - - /* Set the page address */ - - SPI_SEND(priv->spi, SH1101A_PAGEADDR(page)); - - /* Select data transfer */ - - SPI_CMDDATA(priv->spi, SPIDEV_DISPLAY, false); - - /* Then transfer all of the data */ - - (void)SPI_SNDBLOCK(priv->spi, fbptr, pixlen); - - /* De-select and unlock the device */ - - SPI_SELECT(priv->spi, SPIDEV_DISPLAY, false); - ug2864ambag01_unlock(priv->spi); - return OK; -} -#else -# error "Configuration not implemented" -#endif - -/************************************************************************************** - * Name: ug2864ambag01_getrun - * - * Description: - * This method can be used to read a partial raster line from the LCD: - * - * Description: - * This method can be used to write a partial raster line to the LCD. - * - * 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) - * - **************************************************************************************/ - -#if defined(CONFIG_LCD_LANDSCAPE) || defined(CONFIG_LCD_RLANDSCAPE) -static int ug2864ambag01_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer, - size_t npixels) -{ - /* Because of this line of code, we will only be able to support a single UG device */ - - FAR struct ug2864ambag01_dev_s *priv = &g_oleddev; - FAR uint8_t *fbptr; - uint8_t page; - uint8_t fbmask; - uint8_t usrmask; - int pixlen; - uint8_t i; - - lcdvdbg("row: %d col: %d npixels: %d\n", row, col, npixels); - DEBUGASSERT(buffer); - - /* Clip the run to the display */ - - pixlen = npixels; - if ((unsigned int)col + (unsigned int)pixlen > (unsigned int)UG2864AMBAG01_XRES) - { - pixlen = (int)UG2864AMBAG01_XRES - (int)col; - } - - /* Verify that some portion of the run is actually the display */ - - if (pixlen <= 0 || row > UG2864AMBAG01_YRES) - { - return -EINVAL; - } - - /* Perform coordinate conversion for reverse landscape mode */ - -#ifdef CONFIG_LCD_RLANDSCAPE - row = (UG2864AMBAG01_YRES-1) - row; - col = (UG2864AMBAG01_XRES-1) - col; -#endif - - /* Then transfer the display data from the shadow frame buffer memory */ - /* Get the page number. The range of 64 lines is divided up into eight - * pages of 8 lines each. - */ - - page = row >> 3; - - /* Update the shadow frame buffer memory. First determine the pixel - * position in the frame buffer memory. Pixels are organized like - * this: - * - * --------+---+---+---+---+-...-+-----+ - * Segment | 0 | 1 | 2 | 3 | ... | 131 | - * --------+---+---+---+---+-...-+-----+ - * D0 | | X | | | | | - * D1 | | X | | | | | - * D2 | | X | | | | | - * D3 | | X | | | | | - * D4 | | X | | | | | - * D5 | | X | | | | | - * D6 | | X | | | | | - * D7 | | X | | | | | - * --------+---+---+---+---+-...-+-----+ - * - * So, in order to draw a white, horizontal line, at row 45. we - * would have to modify all of the bytes in page 45/8 = 5. We - * would have to set bit 45%8 = 5 in every byte in the page. - */ - - fbmask = 1 << (row & 7); -#ifdef CONFIG_LCD_RLANDSCAPE - fbptr = &priv->fb[page * (UG2864AMBAG01_XRES-1) + col + pixlen]; -#else - fbptr = &priv->fb[page * UG2864AMBAG01_XRES + col]; -#endif -#ifdef CONFIG_NX_PACKEDMSFIRST - usrmask = MS_BIT; -#else - usrmask = LS_BIT; -#endif - - *buffer = 0; - for (i = 0; i < pixlen; i++) - { - /* Set or clear the corresponding bit */ - -#ifdef CONFIG_LCD_RLANDSCAPE - uint8_t byte = *fbptr--; -#else - uint8_t byte = *fbptr++; -#endif - if ((byte & fbmask) != 0) - { - *buffer |= usrmask; - } - - /* Inc/Decrement to the next destination pixel. Hmmmm. It looks like - * this logic could write past the end of the user buffer. Revisit - * this! - */ - -#ifdef CONFIG_NX_PACKEDMSFIRST - if (usrmask == LS_BIT) - { - buffer++; - *buffer = 0; - usrmask = MS_BIT; - } - else - { - usrmask >>= 1; - } -#else - if (usrmask == MS_BIT) - { - buffer++; - *buffer = 0; - usrmask = LS_BIT; - } - else - { - usrmask <<= 1; - } -#endif - } - - return OK; -} -#else -# error "Configuration not implemented" -#endif - -/************************************************************************************** - * Name: ug2864ambag01_getvideoinfo - * - * Description: - * Get information about the LCD video controller configuration. - * - **************************************************************************************/ - -static int ug2864ambag01_getvideoinfo(FAR struct lcd_dev_s *dev, - FAR struct fb_videoinfo_s *vinfo) -{ - DEBUGASSERT(dev && vinfo); - lcdvdbg("fmt: %d xres: %d yres: %d nplanes: %d\n", - g_videoinfo.fmt, g_videoinfo.xres, g_videoinfo.yres, g_videoinfo.nplanes); - memcpy(vinfo, &g_videoinfo, sizeof(struct fb_videoinfo_s)); - return OK; -} - -/************************************************************************************** - * Name: ug2864ambag01_getplaneinfo - * - * Description: - * Get information about the configuration of each LCD color plane. - * - **************************************************************************************/ - -static int ug2864ambag01_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planeno, - FAR struct lcd_planeinfo_s *pinfo) -{ - DEBUGASSERT(pinfo && planeno == 0); - lcdvdbg("planeno: %d bpp: %d\n", planeno, g_planeinfo.bpp); - memcpy(pinfo, &g_planeinfo, sizeof(struct lcd_planeinfo_s)); - return OK; -} - -/************************************************************************************** - * Name: ug2864ambag01_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. - * - **************************************************************************************/ - -static int ug2864ambag01_getpower(FAR struct lcd_dev_s *dev) -{ - FAR struct ug2864ambag01_dev_s *priv = (FAR struct ug2864ambag01_dev_s *)dev; - DEBUGASSERT(priv); - - lcdvdbg("power: %s\n", priv->on ? "ON" : "OFF"); - return priv->on ? CONFIG_LCD_MAXPOWER : 0; -} - -/************************************************************************************** - * Name: ug2864ambag01_setpower - * - * Description: - * Enable/disable LCD panel power (0: full off - CONFIG_LCD_MAXPOWER: full on). On - * backlit LCDs, this setting may correspond to the backlight setting. - * - **************************************************************************************/ - -static int ug2864ambag01_setpower(struct lcd_dev_s *dev, int power) -{ - struct ug2864ambag01_dev_s *priv = (struct ug2864ambag01_dev_s *)dev; - DEBUGASSERT(priv && (unsigned)power <= CONFIG_LCD_MAXPOWER && priv->spi); - - lcdvdbg("power: %d [%d]\n", power, priv->on ? CONFIG_LCD_MAXPOWER : 0); - - /* Lock and select device */ - - ug2864ambag01_lock(priv->spi); - SPI_SELECT(priv->spi, SPIDEV_DISPLAY, true); - - if (power <= 0) - { - /* Turn the display off */ - - (void)SPI_SEND(priv->spi, SH1101A_DISPOFF); - priv->on = false; - } - else - { - /* Turn the display on */ - - (void)SPI_SEND(priv->spi, SH1101A_DISPON); /* Display on, dim mode */ - priv->on = true; - } - - /* De-select and unlock the device */ - - SPI_SELECT(priv->spi, SPIDEV_DISPLAY, false); - ug2864ambag01_unlock(priv->spi); - return OK; -} - -/************************************************************************************** - * Name: ug2864ambag01_getcontrast - * - * Description: - * Get the current contrast setting (0-CONFIG_LCD_MAXCONTRAST). - * - **************************************************************************************/ - -static int ug2864ambag01_getcontrast(struct lcd_dev_s *dev) -{ - struct ug2864ambag01_dev_s *priv = (struct ug2864ambag01_dev_s *)dev; - DEBUGASSERT(priv); - - lcdvdbg("contrast: %d\n", priv->contrast); - return priv->contrast; -} - -/************************************************************************************** - * Name: ug2864ambag01_setcontrast - * - * Description: - * Set LCD panel contrast (0-CONFIG_LCD_MAXCONTRAST). - * - **************************************************************************************/ - -static int ug2864ambag01_setcontrast(struct lcd_dev_s *dev, unsigned int contrast) -{ - struct ug2864ambag01_dev_s *priv = (struct ug2864ambag01_dev_s *)dev; - unsigned int scaled; - - lcdvdbg("contrast: %d\n", contrast); - DEBUGASSERT(priv); - - /* Verify the contrast value */ - -#ifdef CONFIG_DEBUG - if (contrast > CONFIG_LCD_MAXCONTRAST) - { - return -EINVAL; - } -#endif - - /* Scale contrast: newcontrast = 255 * contrast / CONFIG_LCD_MAXCONTRAST - * Where contrast is in the range {1,255} - */ - -#if CONFIG_LCD_MAXCONTRAST != 255 - scaled = ((contrast << 8) - 1) / CONFIG_LCD_MAXCONTRAST; -#else - scaled = contrast; -#endif - - /* Lock and select device */ - - ug2864ambag01_lock(priv->spi); - SPI_SELECT(priv->spi, SPIDEV_DISPLAY, true); - - /* Select command transfer */ - - SPI_CMDDATA(priv->spi, SPIDEV_DISPLAY, true); - - /* Set the contrast */ - - (void)SPI_SEND(priv->spi, SH1101A_CONTRAST_MODE); /* Set contrast control register */ - (void)SPI_SEND(priv->spi, SH1101A_CONTRAST(scaled)); /* Data 1: Set 1 of 256 contrast steps */ - priv->contrast = contrast; - - /* De-select and unlock the device */ - - SPI_SELECT(priv->spi, SPIDEV_DISPLAY, false); - ug2864ambag01_unlock(priv->spi); - return OK; -} - -/************************************************************************************** - * Public Functions - **************************************************************************************/ - -/************************************************************************************** - * Name: ug2864ambag01_initialize - * - * Description: - * Initialize the UG-2864AMBAG01 video hardware. The initial state of the - * OLED is fully initialized, display memory cleared, and the OLED ready - * to use, but with the power setting at 0 (full off == sleep mode). - * - * Input Parameters: - * - * spi - A reference to the SPI driver instance. - * devno - A value in the range of 0 through CONFIG_UG2864AMBAG01_NINTERFACES-1. - * This allows support for multiple OLED devices. - * - * Returned Value: - * - * On success, this function returns a reference to the LCD object for - * the specified OLED. NULL is returned on any failure. - * - **************************************************************************************/ - -FAR struct lcd_dev_s *ug2864ambag01_initialize(FAR struct spi_dev_s *spi, unsigned int devno) -{ - FAR struct ug2864ambag01_dev_s *priv = &g_oleddev; - - lcdvdbg("Initializing\n"); - DEBUGASSERT(spi && devno == 0); - - /* Save the reference to the SPI device */ - - priv->spi = spi; - - /* Configure the SPI */ - - ug2864ambag01_configspi(spi); - - /* Lock and select device */ - - ug2864ambag01_lock(priv->spi); - SPI_SELECT(spi, SPIDEV_DISPLAY, true); - - /* Select command transfer */ - - SPI_CMDDATA(spi, SPIDEV_DISPLAY, true); - - /* Configure the device */ - - SPI_SEND(spi, SH1101A_DISPOFF); /* Display off */ - SPI_SEND(spi, SH1101A_SETCOLL(0)); /* Set lower column address */ - SPI_SEND(spi, SH1101A_SETCOLH(0)); /* Set higher column address */ - SPI_SEND(spi, SH1101A_STARTLINE(0)); /* Set display start line */ - SPI_SEND(spi, SH1101A_PAGEADDR(0)); /* Set page address */ - SPI_SEND(spi, SH1101A_CONTRAST_MODE); /* Contrast control */ - SPI_SEND(spi ,UG2864AMBAG01_CONTRAST); /* Default contrast */ - SPI_SEND(spi, SH1101A_REMAPPLEFT); /* Set segment remap left */ - SPI_SEND(spi, SH1101A_EDISPOFF); /* Normal display */ - SPI_SEND(spi, SH1101A_NORMAL); /* Normal (un-reversed) display mode */ - SPI_SEND(spi, SH1101A_MRATIO_MODE); /* Multiplex ratio */ - SPI_SEND(spi, SH1101A_MRATIO(0x3f)); /* Duty = 1/64 */ - SPI_SEND(spi, SH1101A_SCANTOCOM0); /* Com scan direction: Scan from COM[n-1] to COM[0] */ - SPI_SEND(spi, SH1101A_DISPOFFS_MODE); /* Set display offset */ - SPI_SEND(spi, SH1101A_DISPOFFS(0)); - SPI_SEND(spi, SH1101A_CLKDIV_SET); /* Set clock divider */ - SPI_SEND(spi, SH1101A_CLKDIV(0,0)); - SPI_SEND(spi, SH1101A_CMNPAD_CONFIG); /* Set common pads */ - SPI_SEND(spi, SH1101A_CMNPAD(0x10)); - SPI_SEND(spi, SH1101A_VCOM_SET); - SPI_SEND(spi, SH1101A_VCOM(0x40)); - SPI_SEND(spi, SH1101A_DCDC_MODE); /* DC/DC control mode: on */ - SPI_SEND(spi, SH1101A_DCDC_ON); - SPI_SEND(spi, SH1101A_DISPON); /* display ON */ - - /* De-select and unlock the device */ - - SPI_SELECT(spi, SPIDEV_DISPLAY, false); - ug2864ambag01_unlock(priv->spi); - - /* Clear the display */ - - up_mdelay(100); - ug2864ambag01_fill(&priv->dev, UG_Y1_BLACK); - return &priv->dev; -} - -/************************************************************************************** - * Name: ug2864ambag01_fill - * - * Description: - * This non-standard method can be used to clear the entire display by writing one - * color to the display. This is much faster than writing a series of runs. - * - * Input Parameters: - * priv - Reference to private driver structure - * - * Assumptions: - * Caller has selected the OLED section. - * - **************************************************************************************/ - -void ug2864ambag01_fill(FAR struct lcd_dev_s *dev, uint8_t color) -{ - FAR struct ug2864ambag01_dev_s *priv = &g_oleddev; - unsigned int page; - - /* Make an 8-bit version of the selected color */ - - if (color & 1) - { - color = 0xff; - } - else - { - color = 0; - } - - /* Initialize the framebuffer */ - - memset(priv->fb, color, UG2864AMBAG01_FBSIZE); - - /* Lock and select device */ - - ug2864ambag01_lock(priv->spi); - SPI_SELECT(priv->spi, SPIDEV_DISPLAY, true); - - /* Visit each page */ - - for (page = 0; page < UG2864AMBAG01_DEV_PAGES; page++) - { - /* Select command transfer */ - - SPI_CMDDATA(priv->spi, SPIDEV_DISPLAY, true); - - /* Set the column address to the XOFFSET value */ - - SPI_SEND(priv->spi, SH1101A_SETCOLL(UG2864AMBAG01_DEV_XOFFSET)); - SPI_SEND(priv->spi, SH1101A_SETCOLH(0)); - - /* Set the page address */ - - SPI_SEND(priv->spi, SH1101A_PAGEADDR(page)); - - /* Select data transfer */ - - SPI_CMDDATA(priv->spi, SPIDEV_DISPLAY, false); - - /* Transfer one page of the selected color */ - - (void)SPI_SNDBLOCK(priv->spi, &priv->fb[page * UG2864AMBAG01_XRES], - UG2864AMBAG01_XRES); - } - - /* De-select and unlock the device */ - - SPI_SELECT(priv->spi, SPIDEV_DISPLAY, false); - ug2864ambag01_unlock(priv->spi); -} - -#endif /* CONFIG_LCD_UG2864AMBAG01 */ diff --git a/nuttx/drivers/lcd/ug-2864hsweg01.c b/nuttx/drivers/lcd/ug-2864hsweg01.c deleted file mode 100644 index 02a59b104..000000000 --- a/nuttx/drivers/lcd/ug-2864hsweg01.c +++ /dev/null @@ -1,1218 +0,0 @@ -/************************************************************************************** - * drivers/lcd/ug-2864hsweg01.c - * Driver for Univision UG-2864HSWEG01 OLED display (wih SSD1306 controller) in SPI - * mode - * - * Copyright (C) 2012 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt <gnutt@nuttx.org> - * - * References: - * 1. Product Specification (Preliminary), Part Name: OEL Display Module, Part ID: - * UG-2864HSWEG01, Doc No: SAS1-9046-B, Univision Technology Inc. - * 2. SSD1306, 128 X 64 Dot Matrix OLED/PLED, Preliminary Segment/Common Driver with - * Controller, Solomon Systech - * - * 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 written 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. - * - **************************************************************************************/ -/************************************************************************************** - * Device memory organization: - * - * +----------------------------+ - * | Column | - * --------+----+---+---+---+-...-+-----+ - * Page | 0 | 1 | 2 | 3 | ... | 127 | - * --------+----+---+---+---+-...-+-----+ - * Page 0 | D0 | X | | | | | - * | D1 | X | | | | | - * | D2 | X | | | | | - * | D3 | X | | | | | - * | D4 | X | | | | | - * | D5 | X | | | | | - * | D6 | X | | | | | - * | D7 | X | | | | | - * --------+----+---+---+---+-...-+-----+ - * Page 1 | | | | | | | - * --------+----+---+---+---+-...-+-----+ - * Page 2 | | | | | | | - * --------+----+---+---+---+-...-+-----+ - * Page 3 | | | | | | | - * --------+----+---+---+---+-...-+-----+ - * Page 4 | | | | | | | - * --------+----+---+---+---+-...-+-----+ - * Page 5 | | | | | | | - * --------+----+---+---+---+-...-+-----+ - * Page 6 | | | | | | | - * --------+----+---+---+---+-...-+-----+ - * Page 7 | | | | | | | - * --------+----+---+---+---+-...-+-----+ - * - * -----------------------------------+--------------------------------------- - * Landscape Display: | Reverse Landscape Display: - * --------+-----------------------+ | --------+---------------------------+ - * | Column | | | Column | - * --------+---+---+---+-...-+-----+ | --------+-----+-----+-----+-...-+---+ - * Page 0 | 0 | 1 | 2 | | 127 | | Page 7 | 127 | 126 | 125 | | 0 | - * --------+---+---+---+-...-+-----+ | --------+-----+-----+-----+-...-+---+ - * Page 1 | V | | Page 6 | ^ | - * --------+---+---+---+-...-+-----+ | --------+-----+-----+-----+-...-+---+ - * Page 2 | V | | Page 5 | ^ | - * --------+---+---+---+-...-+-----+ | --------+-----+-----+-----+-...-+---+ - * Page 3 | V | | Page 4 | ^ | - * --------+---+---+---+-...-+-----+ | --------+-----+-----+-----+-...-+---+ - * Page 4 | V | | Page 3 | ^ | - * --------+---+---+---+-...-+-----+ | --------+-----+-----+-----+-...-+---+ - * Page 5 | V | | Page 2 | ^ | - * --------+---+---+---+-...-+-----+ | --------+-----+-----+-----+-...-+---+ - * Page 6 | V | | Page 1 | ^ | - * --------+---+---+---+-...-+-----+ | --------+-----+-----+-----+-...-+---+ - * Page 7 | V | | Page 0 | ^ | - * --------+---+---+---+-...-+-----+ | --------+-----+-----+-----+-...-+---+ - * -----------------------------------+--------------------------------------- - * - * -----------------------------------+--------------------------------------- - * Portrait Display: | Reverse Portrait Display: - * -----------+---------------------+ | -----------+---------------------+ - * | Page | | | Page | - * -----------+---+---+---+-...-+---+ | -----------+---+---+---+-...-+---+ - * Column 0 | 0 | 1 | 2 | | 7 | | Column 127 | 7 | 6 | 5 | | 0 | - * -----------+---+---+---+-...-+---+ | -----------+---+---+---+-...-+---+ - * Column 1 | > > > > > | | Column 126 | | - * -----------+---+---+---+-...-+---+ | -----------+---+---+---+-...-+---+ - * Column 2 | | | Column 125 | | - * -----------+---+---+---+-...-+---+ | -----------+---+---+---+-...-+---+ - * ... | | | ... | | - * -----------+---+---+---+-...-+---+ | -----------+---+---+---+-...-+---+ - * Column 127 | | | Column 0 | < < < < < | - * -----------+---+---+---+-...-+---+ | -----------+---+---+---+-...-+---+ - * -----------------------------------+---------------------------------------- - **************************************************************************************/ - -/************************************************************************************** - * Included Files - **************************************************************************************/ - -#include <nuttx/config.h> - -#include <sys/types.h> -#include <stdint.h> -#include <stdbool.h> -#include <string.h> -#include <errno.h> -#include <debug.h> - -#include <nuttx/arch.h> -#include <nuttx/spi.h> -#include <nuttx/lcd/lcd.h> -#include <nuttx/lcd/ug-2864hsweg01.h> - -#include <arch/irq.h> - -#ifdef CONFIG_LCD_UG2864HSWEG01 - -/************************************************************************************** - * Pre-processor Definitions - **************************************************************************************/ -/* Configuration **********************************************************************/ -/* Limitations of the current configuration that I hope to fix someday */ - -#if CONFIG_UG2864HSWEG01_NINTERFACES != 1 -# warning "This implementation supports only a single OLED device" -# undef CONFIG_UG2864HSWEG01_NINTERFACES -# define CONFIG_UG2864HSWEG01_NINTERFACES 1 -#endif - -#if defined(CONFIG_LCD_PORTRAIT) || defined(CONFIG_LCD_RPORTRAIT) -# warning "No support yet for portrait modes" -# define CONFIG_LCD_LANDSCAPE 1 -# undef CONFIG_LCD_PORTRAIT -# undef CONFIG_LCD_RLANDSCAPE -# undef CONFIG_LCD_RPORTRAIT -#elif defined(CONFIG_LCD_RLANDSCAPE) -# warning "Reverse landscape mode is untested and, hence, probably buggy" -#endif - -/* SSD1306 Commands *******************************************************************/ - -#define SSD1306_SETCOLL(ad) (0x00 | ((ad) & 0x0f)) /* Set Lower Column Address: (00h - 0fh) */ -#define SSD1306_SETCOLH(ad) (0x10 | ((ad) & 0x0f)) /* Set Higher Column Address: (10h - 1fh) */ -#define SSD1306_STARTLINE(ln) (0x40 | ((ln) & 0x3f)) /* Set Display Start Line: (40h - 7fh) */ -#define SSD1306_CONTRAST_MODE (0x81) /* Set Contrast Control Register: (Double Bytes Command) */ -# define SSD1306_CONTRAST(c) (c) -#define SSD1306_SEGREMAP(m) (0xa0 | ((m) & 0x01)) /* Set Segment Re-map: (a0h - a1h) */ -# define SSD1306_REMAPRIGHT SSD1306_SEGREMAP(0) /* Right rotation */ -# define SSD1306_REMAPPLEFT SSD1306_SEGREMAP(1) /* Left rotation */ -#define SSD1306_EDISPOFFON(s) (0xa4 | ((s) & 0x01)) /* Set Entire Display OFF/ON: (a4h - a5h) */ -# define SSD1306_EDISPOFF SSD1306_EDISPOFFON(0) /* Display off */ -# define SSD1306_EDISPON SSD1306_EDISPOFFON(1) /* Display on */ -#define SSD1306_NORMREV(s) (0xa6 | ((s) & 0x01)) /* Set Normal/Reverse Display: (a6h -a7h) */ -# define SSD1306_NORMAL SSD1306_NORMREV(0) /* Normal display */ -# define SSD1306_REVERSE SSD1306_NORMREV(1) /* Reverse display */ -#define SSD1306_MRATIO_MODE (0xa8) /* Set Multiplex Ration: (Double Bytes Command) */ -# define SSD1306_MRATIO(d) ((d) & 0x3f) -#define SSD1306_DCDC_MODE (0xad) /* Set DC-DC OFF/ON: (Double Bytes Command) */ -# define SSD1306_DCDC_OFF (0x8a) -# define SSD1306_DCDC_ON (0x8b) - -#define SSD1306_DISPOFFON(s) (0xae | ((s) & 0x01)) /* Display OFF/ON: (aeh - afh) */ -# define SSD1306_DISPOFF SSD1306_DISPOFFON(0) /* Display off */ -# define SSD1306_DISPON SSD1306_DISPOFFON(1) /* Display on */ -#define SSD1306_PAGEADDR(a) (0xb0 | ((a) & 0x0f)) /* Set Page Address: (b0h - b7h) */ -#define SSD1306_SCANDIR(d) (0xc0 | ((d) & 0x08)) /* Set Common Output Scan Direction: (c0h - c8h) */ -# define SSD1306_SCANFROMCOM0 SSD1306_SCANDIR(0x00) /* Scan from COM[0] to COM[n-1]*/ -# define SSD1306_SCANTOCOM0 SSD1306_SCANDIR(0x08) /* Scan from COM[n-1] to COM[0] */ -#define SSD1306_DISPOFFS_MODE (0xd3) /* Set Display Offset: (Double Bytes Command) */ -# define SSD1306_DISPOFFS(o) ((o) & 0x3f) -#define SSD1306_CLKDIV_SET (0xd5) /* Set Display Clock Divide Ratio/Oscillator Frequency: (Double Bytes Command) */ -# define SSD1306_CLKDIV(f,d) ((((f) & 0x0f) << 4) | ((d) & 0x0f)) -#define SSD1306_CHRGPER_SET (0xd9) /* Set Dis-charge/Pre-charge Period: (Double Bytes Command) */ -# define SSD1306_CHRGPER(d,p) ((((d) & 0x0f) << 4) | ((p) & 0x0f)) -#define SSD1306_CMNPAD_CONFIG (0xda) /* Set Common pads hardware configuration: (Double Bytes Command) */ -# define SSD1306_CMNPAD(c) ((0x02) | ((c) & 0x10)) -#define SSD1306_VCOM_SET (0xdb) /* Set VCOM Deselect Level: (Double Bytes Command) */ -# define SSD1306_VCOM(v) (v) - -#define SSD1306_CHRPUMP_SET (0x8d) /* Charge Pump Setting */ -# define SSD1306_CHRPUMP_ON (0x14) -# define SSD1306_CHRPUMP_OFF (0x10) - -#define SSD1306_RMWSTART (0xe0) /* Read-Modify-Write: (e0h) */ -#define SSD1306_NOP (0xe3) /* NOP: (e3h) */ -#define SSD1306_END (0xee) /* End: (eeh) */ - -#define SSD1306_WRDATA(d) (d) /* Write Display Data */ -#define SSD1306_STATUS_BUSY (0x80) /* Read Status */ -#define SSD1306_STATUS_ONOFF (0x40) -#define SSD1306_RDDATA(d) (d) /* Read Display Data */ - -/* Color Properties *******************************************************************/ -/* Display Resolution - * - * The SSD1306 display controller can handle a resolution of 132x64. The UG-2864HSWEG01 - * on the base board is 128x64. - */ - -#define UG2864HSWEG01_DEV_XRES 128 /* Only 128 of 131 columns used */ -#define UG2864HSWEG01_DEV_YRES 64 /* 8 pages each 8 rows */ -#define UG2864HSWEG01_DEV_XOFFSET 2 /* Offset to logical column 0 */ -#define UG2864HSWEG01_DEV_PAGES 8 /* 8 pages */ - -#if defined(CONFIG_LCD_LANDSCAPE) || defined(CONFIG_LCD_RLANDSCAPE) -# define UG2864HSWEG01_XRES UG2864HSWEG01_DEV_XRES -# define UG2864HSWEG01_YRES UG2864HSWEG01_DEV_YRES -#else -# define UG2864HSWEG01_XRES UG2864HSWEG01_DEV_YRES -# define UG2864HSWEG01_YRES UG2864HSWEG01_DEV_XRES -#endif - -/* Color depth and format */ - -#define UG2864HSWEG01_BPP 1 -#define UG2864HSWEG01_COLORFMT FB_FMT_Y1 - -/* Bytes per logical row and actual device row */ - -#define UG2864HSWEG01_XSTRIDE (UG2864HSWEG01_XRES >> 3) -#define UG2864HSWEG01_YSTRIDE (UG2864HSWEG01_YRES >> 3) - -/* Default contrast */ - -#define UG2864HSWEG01_CONTRAST (128) - -/* The size of the shadow frame buffer or one row buffer. - * - * Frame buffer size: 128 columns x 64 rows / 8 bits-per-pixel - * Row size: 128 columns x 8 rows-per-page / 8 bits-per-pixel - */ - -#define UG2864HSWEG01_FBSIZE (UG2864HSWEG01_XSTRIDE * UG2864HSWEG01_YRES) -#define UG2864HSWEG01_ROWSIZE (UG2864HSWEG01_XSTRIDE) - -/* Bit helpers */ - -#define LS_BIT (1 << 0) -#define MS_BIT (1 << 7) - -/* Debug ******************************************************************************/ - -#ifdef CONFIG_DEBUG_LCD -# define lcddbg(format, arg...) dbg(format, ##arg) -# define lcdvdbg(format, arg...) vdbg(format, ##arg) -#else -# define lcddbg(x...) -# define lcdvdbg(x...) -#endif - -/************************************************************************************** - * Private Type Definition - **************************************************************************************/ - -/* This structure describes the state of this driver */ - -struct ug2864hsweg01_dev_s -{ - struct lcd_dev_s dev; /* Publically visible device structure */ - - /* Private LCD-specific information follows */ - - FAR struct spi_dev_s *spi; /* Cached SPI device reference */ - uint8_t contrast; /* Current contrast setting */ - bool on; /* true: display is on */ - - - /* The SSD1306 does not support reading from the display memory in SPI mode. - * Since there is 1 BPP and access is byte-by-byte, it is necessary to keep - * a shadow copy of the framebuffer memory. At 128x64, this amounts to 1KB. - */ - - uint8_t fb[UG2864HSWEG01_FBSIZE]; -}; - -/************************************************************************************** - * Private Function Protototypes - **************************************************************************************/ - -/* Low-level SPI helpers */ - -#ifdef CONFIG_SPI_OWNBUS -static inline void ug2864hsweg01_configspi(FAR struct spi_dev_s *spi); -# define ug2864hsweg01_lock(spi) -# define ug2864hsweg01_unlock(spi) -#else -# define ug2864hsweg01_configspi(spi) -static void ug2864hsweg01_lock(FAR struct spi_dev_s *spi); -static void ug2864hsweg01_unlock(FAR struct spi_dev_s *spi); -#endif - -/* LCD Data Transfer Methods */ - -static int ug2864hsweg01_putrun(fb_coord_t row, fb_coord_t col, - FAR const uint8_t *buffer, size_t npixels); -static int ug2864hsweg01_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer, - size_t npixels); - -/* LCD Configuration */ - -static int ug2864hsweg01_getvideoinfo(FAR struct lcd_dev_s *dev, - FAR struct fb_videoinfo_s *vinfo); -static int ug2864hsweg01_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planeno, - FAR struct lcd_planeinfo_s *pinfo); - -/* LCD RGB Mapping */ - -#ifdef CONFIG_FB_CMAP -# error "RGB color mapping not supported by this driver" -#endif - -/* Cursor Controls */ - -#ifdef CONFIG_FB_HWCURSOR -# error "Cursor control not supported by this driver" -#endif - -/* LCD Specific Controls */ - -static int ug2864hsweg01_getpower(struct lcd_dev_s *dev); -static int ug2864hsweg01_setpower(struct lcd_dev_s *dev, int power); -static int ug2864hsweg01_getcontrast(struct lcd_dev_s *dev); -static int ug2864hsweg01_setcontrast(struct lcd_dev_s *dev, unsigned int contrast); - -/************************************************************************************** - * Private Data - **************************************************************************************/ - -/* This is working memory allocated by the LCD driver for each LCD device - * and for each color plane. This memory will hold one raster line of data. - * The size of the allocated run buffer must therefore be at least - * (bpp * xres / 8). Actual alignment of the buffer must conform to the - * bitwidth of the underlying pixel type. - * - * If there are multiple planes, they may share the same working buffer - * because different planes will not be operate on concurrently. However, - * if there are multiple LCD devices, they must each have unique run buffers. - */ - -static uint8_t g_runbuffer[UG2864HSWEG01_ROWSIZE]; - -/* This structure describes the overall LCD video controller */ - -static const struct fb_videoinfo_s g_videoinfo = -{ - .fmt = UG2864HSWEG01_COLORFMT, /* Color format: RGB16-565: RRRR RGGG GGGB BBBB */ - .xres = UG2864HSWEG01_XRES, /* Horizontal resolution in pixel columns */ - .yres = UG2864HSWEG01_YRES, /* Vertical resolution in pixel rows */ - .nplanes = 1, /* Number of color planes supported */ -}; - -/* This is the standard, NuttX Plane information object */ - -static const struct lcd_planeinfo_s g_planeinfo = -{ - .putrun = ug2864hsweg01_putrun, /* Put a run into LCD memory */ - .getrun = ug2864hsweg01_getrun, /* Get a run from LCD memory */ - .buffer = (uint8_t*)g_runbuffer, /* Run scratch buffer */ - .bpp = UG2864HSWEG01_BPP, /* Bits-per-pixel */ -}; - -/* This is the OLED driver instance (only a single device is supported for now) */ - -static struct ug2864hsweg01_dev_s g_oleddev = -{ - .dev = - { - /* LCD Configuration */ - - .getvideoinfo = ug2864hsweg01_getvideoinfo, - .getplaneinfo = ug2864hsweg01_getplaneinfo, - - /* LCD RGB Mapping -- Not supported */ - /* Cursor Controls -- Not supported */ - - /* LCD Specific Controls */ - - .getpower = ug2864hsweg01_getpower, - .setpower = ug2864hsweg01_setpower, - .getcontrast = ug2864hsweg01_getcontrast, - .setcontrast = ug2864hsweg01_setcontrast, - }, -}; - -/************************************************************************************** - * Private Functions - **************************************************************************************/ - -/************************************************************************************** - * Name: ug2864hsweg01_configspi - * - * Description: - * Configure the SPI for use with the UG-2864HSWEG01 - * - * Input Parameters: - * spi - Reference to the SPI driver structure - * - * Returned Value: - * None - * - * Assumptions: - * - **************************************************************************************/ - -#ifdef CONFIG_SPI_OWNBUS -static inline void ug2864hsweg01_configspi(FAR struct spi_dev_s *spi) -{ - lcdvdbg("Mode: %d Bits: 8 Frequency: %d\n", - CONFIG_UG2864HSWEG01_SPIMODE, CONFIG_UG2864HSWEG01_FREQUENCY); - - /* Configure SPI for the UG-2864HSWEG01. But only if we own the SPI bus. Otherwise, - * don't bother because it might change. - */ - - SPI_SETMODE(spi, CONFIG_UG2864HSWEG01_SPIMODE); - SPI_SETBITS(spi, 8); - SPI_SETFREQUENCY(spi, CONFIG_UG2864HSWEG01_FREQUENCY); -} -#endif - -/************************************************************************************** - * Name: ug2864hsweg01_lock - * - * Description: - * Select the SPI, locking and re-configuring if necessary - * - * Input Parameters: - * spi - Reference to the SPI driver structure - * - * Returned Value: - * None - * - * Assumptions: - * - **************************************************************************************/ - -#ifndef CONFIG_SPI_OWNBUS -static inline void ug2864hsweg01_lock(FAR struct spi_dev_s *spi) -{ - /* Lock the SPI bus if there are multiple devices competing for the SPI bus. */ - - SPI_LOCK(spi, true); - - /* Now make sure that the SPI bus is configured for the UG-2864HSWEG01 (it - * might have gotten configured for a different device while unlocked) - */ - - SPI_SETMODE(spi, CONFIG_UG2864HSWEG01_SPIMODE); - SPI_SETBITS(spi, 8); - SPI_SETFREQUENCY(spi, CONFIG_UG2864HSWEG01_FREQUENCY); -} -#endif - -/************************************************************************************** - * Name: ug2864hsweg01_unlock - * - * Description: - * De-select the SPI - * - * Input Parameters: - * spi - Reference to the SPI driver structure - * - * Returned Value: - * None - * - * Assumptions: - * - **************************************************************************************/ - -#ifndef CONFIG_SPI_OWNBUS -static inline void ug2864hsweg01_unlock(FAR struct spi_dev_s *spi) -{ - /* De-select UG-2864HSWEG01 chip and relinquish the SPI bus. */ - - SPI_LOCK(spi, false); -} -#endif - -/************************************************************************************** - * Name: ug2864hsweg01_putrun - * - * Description: - * This method can be used to write a partial raster line to the LCD. - * - * Input Parameters: - * row - Starting row to write to (range: 0 <= row < yres) - * col - Starting column to write to (range: 0 <= col <= xres-npixels) - * buffer - The buffer containing the run to be written to the LCD - * npixels - The number of pixels to write to the LCD - * (range: 0 < npixels <= xres-col) - * - **************************************************************************************/ - -#if defined(CONFIG_LCD_LANDSCAPE) || defined(CONFIG_LCD_RLANDSCAPE) -static int ug2864hsweg01_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer, - size_t npixels) -{ - /* Because of this line of code, we will only be able to support a single UG device */ - - FAR struct ug2864hsweg01_dev_s *priv = (FAR struct ug2864hsweg01_dev_s *)&g_oleddev; - FAR uint8_t *fbptr; - FAR uint8_t *ptr; - uint8_t devcol; - uint8_t fbmask; - uint8_t page; - uint8_t usrmask; - int pixlen; - uint8_t i; - - lcdvdbg("row: %d col: %d npixels: %d\n", row, col, npixels); - DEBUGASSERT(buffer); - - /* Clip the run to the display */ - - pixlen = npixels; - if ((unsigned int)col + (unsigned int)pixlen > (unsigned int)UG2864HSWEG01_XRES) - { - pixlen = (int)UG2864HSWEG01_XRES - (int)col; - } - - /* Verify that some portion of the run remains on the display */ - - if (pixlen <= 0 || row > UG2864HSWEG01_YRES) - { - return OK; - } - - /* Perform coordinate conversion for reverse landscape mode */ - -#ifdef CONFIG_LCD_RLANDSCAPE - row = (UG2864HSWEG01_YRES-1) - row; - col = (UG2864HSWEG01_XRES-1) - col; -#endif - - /* Get the page number. The range of 64 lines is divided up into eight - * pages of 8 lines each. - */ - - page = row >> 3; - - /* Update the shadow frame buffer memory. First determine the pixel - * position in the frame buffer memory. Pixels are organized like - * this: - * - * --------+---+---+---+---+-...-+-----+ - * Segment | 0 | 1 | 2 | 3 | ... | 131 | - * --------+---+---+---+---+-...-+-----+ - * D0 | | X | | | | | - * D1 | | X | | | | | - * D2 | | X | | | | | - * D3 | | X | | | | | - * D4 | | X | | | | | - * D5 | | X | | | | | - * D6 | | X | | | | | - * D7 | | X | | | | | - * --------+---+---+---+---+-...-+-----+ - * - * So, in order to draw a white, horizontal line, at row 45. we - * would have to modify all of the bytes in page 45/8 = 5. We - * would have to set bit 45%8 = 5 in every byte in the page. - */ - - fbmask = 1 << (row & 7); - fbptr = &priv->fb[page * UG2864HSWEG01_XRES + col]; -#ifdef CONFIG_LCD_RLANDSCAPE - ptr = fbptr + pixlen - 1; -#else - ptr = fbptr; -#endif -#ifdef CONFIG_NX_PACKEDMSFIRST - usrmask = MS_BIT; -#else - usrmask = LS_BIT; -#endif - - for (i = 0; i < pixlen; i++) - { - /* Set or clear the corresponding bit */ - -#ifdef CONFIG_LCD_RLANDSCAPE - if ((*buffer & usrmask) != 0) - { - *ptr-- |= fbmask; - } - else - { - *ptr-- &= ~fbmask; - } -#else - if ((*buffer & usrmask) != 0) - { - *ptr++ |= fbmask; - } - else - { - *ptr++ &= ~fbmask; - } -#endif - - /* Inc/Decrement to the next source pixel */ - -#ifdef CONFIG_NX_PACKEDMSFIRST - if (usrmask == LS_BIT) - { - buffer++; - usrmask = MS_BIT; - } - else - { - usrmask >>= 1; - } -#else - if (usrmask == MS_BIT) - { - buffer++; - usrmask = LS_BIT; - } - else - { - usrmask <<= 1; - } -#endif - } - - /* Offset the column position to account for smaller horizontal - * display range. - */ - - devcol = col + UG2864HSWEG01_DEV_XOFFSET; - - /* Lock and select device */ - - ug2864hsweg01_lock(priv->spi); - SPI_SELECT(priv->spi, SPIDEV_DISPLAY, true); - - /* Select command transfer */ - - SPI_CMDDATA(priv->spi, SPIDEV_DISPLAY, true); - - /* Set the starting position for the run */ - /* Set the column address to the XOFFSET value */ - - SPI_SEND(priv->spi, SSD1306_SETCOLL(devcol & 0x0f)); - SPI_SEND(priv->spi, SSD1306_SETCOLH(devcol >> 4)); - - /* Set the page address */ - - SPI_SEND(priv->spi, SSD1306_PAGEADDR(page)); - - /* Select data transfer */ - - SPI_CMDDATA(priv->spi, SPIDEV_DISPLAY, false); - - /* Then transfer all of the data */ - - (void)SPI_SNDBLOCK(priv->spi, fbptr, pixlen); - - /* De-select and unlock the device */ - - SPI_SELECT(priv->spi, SPIDEV_DISPLAY, false); - ug2864hsweg01_unlock(priv->spi); - return OK; -} -#else -# error "Configuration not implemented" -#endif - -/************************************************************************************** - * Name: ug2864hsweg01_getrun - * - * Description: - * This method can be used to read a partial raster line from the LCD: - * - * Description: - * This method can be used to write a partial raster line to the LCD. - * - * 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) - * - **************************************************************************************/ - -#if defined(CONFIG_LCD_LANDSCAPE) || defined(CONFIG_LCD_RLANDSCAPE) -static int ug2864hsweg01_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer, - size_t npixels) -{ - /* Because of this line of code, we will only be able to support a single UG device */ - - FAR struct ug2864hsweg01_dev_s *priv = &g_oleddev; - FAR uint8_t *fbptr; - uint8_t page; - uint8_t fbmask; - uint8_t usrmask; - int pixlen; - uint8_t i; - - lcdvdbg("row: %d col: %d npixels: %d\n", row, col, npixels); - DEBUGASSERT(buffer); - - /* Clip the run to the display */ - - pixlen = npixels; - if ((unsigned int)col + (unsigned int)pixlen > (unsigned int)UG2864HSWEG01_XRES) - { - pixlen = (int)UG2864HSWEG01_XRES - (int)col; - } - - /* Verify that some portion of the run is actually the display */ - - if (pixlen <= 0 || row > UG2864HSWEG01_YRES) - { - return -EINVAL; - } - - /* Perform coordinate conversion for reverse landscape mode */ - -#ifdef CONFIG_LCD_RLANDSCAPE - row = (UG2864HSWEG01_YRES-1) - row; - col = (UG2864HSWEG01_XRES-1) - col; -#endif - - /* Then transfer the display data from the shadow frame buffer memory */ - /* Get the page number. The range of 64 lines is divided up into eight - * pages of 8 lines each. - */ - - page = row >> 3; - - /* Update the shadow frame buffer memory. First determine the pixel - * position in the frame buffer memory. Pixels are organized like - * this: - * - * --------+---+---+---+---+-...-+-----+ - * Segment | 0 | 1 | 2 | 3 | ... | 131 | - * --------+---+---+---+---+-...-+-----+ - * D0 | | X | | | | | - * D1 | | X | | | | | - * D2 | | X | | | | | - * D3 | | X | | | | | - * D4 | | X | | | | | - * D5 | | X | | | | | - * D6 | | X | | | | | - * D7 | | X | | | | | - * --------+---+---+---+---+-...-+-----+ - * - * So, in order to draw a white, horizontal line, at row 45. we - * would have to modify all of the bytes in page 45/8 = 5. We - * would have to set bit 45%8 = 5 in every byte in the page. - */ - - fbmask = 1 << (row & 7); -#ifdef CONFIG_LCD_RLANDSCAPE - fbptr = &priv->fb[page * (UG2864HSWEG01_XRES-1) + col + pixlen]; -#else - fbptr = &priv->fb[page * UG2864HSWEG01_XRES + col]; -#endif -#ifdef CONFIG_NX_PACKEDMSFIRST - usrmask = MS_BIT; -#else - usrmask = LS_BIT; -#endif - - *buffer = 0; - for (i = 0; i < pixlen; i++) - { - /* Set or clear the corresponding bit */ - -#ifdef CONFIG_LCD_RLANDSCAPE - uint8_t byte = *fbptr--; -#else - uint8_t byte = *fbptr++; -#endif - if ((byte & fbmask) != 0) - { - *buffer |= usrmask; - } - - /* Inc/Decrement to the next destination pixel. Hmmmm. It looks like - * this logic could write past the end of the user buffer. Revisit - * this! - */ - -#ifdef CONFIG_NX_PACKEDMSFIRST - if (usrmask == LS_BIT) - { - buffer++; - *buffer = 0; - usrmask = MS_BIT; - } - else - { - usrmask >>= 1; - } -#else - if (usrmask == MS_BIT) - { - buffer++; - *buffer = 0; - usrmask = LS_BIT; - } - else - { - usrmask <<= 1; - } -#endif - } - - return OK; -} -#else -# error "Configuration not implemented" -#endif - -/************************************************************************************** - * Name: ug2864hsweg01_getvideoinfo - * - * Description: - * Get information about the LCD video controller configuration. - * - **************************************************************************************/ - -static int ug2864hsweg01_getvideoinfo(FAR struct lcd_dev_s *dev, - FAR struct fb_videoinfo_s *vinfo) -{ - DEBUGASSERT(dev && vinfo); - lcdvdbg("fmt: %d xres: %d yres: %d nplanes: %d\n", - g_videoinfo.fmt, g_videoinfo.xres, g_videoinfo.yres, g_videoinfo.nplanes); - memcpy(vinfo, &g_videoinfo, sizeof(struct fb_videoinfo_s)); - return OK; -} - -/************************************************************************************** - * Name: ug2864hsweg01_getplaneinfo - * - * Description: - * Get information about the configuration of each LCD color plane. - * - **************************************************************************************/ - -static int ug2864hsweg01_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planeno, - FAR struct lcd_planeinfo_s *pinfo) -{ - DEBUGASSERT(pinfo && planeno == 0); - lcdvdbg("planeno: %d bpp: %d\n", planeno, g_planeinfo.bpp); - memcpy(pinfo, &g_planeinfo, sizeof(struct lcd_planeinfo_s)); - return OK; -} - -/************************************************************************************** - * Name: ug2864hsweg01_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. - * - **************************************************************************************/ - -static int ug2864hsweg01_getpower(FAR struct lcd_dev_s *dev) -{ - FAR struct ug2864hsweg01_dev_s *priv = (FAR struct ug2864hsweg01_dev_s *)dev; - DEBUGASSERT(priv); - - lcdvdbg("power: %s\n", priv->on ? "ON" : "OFF"); - return priv->on ? CONFIG_LCD_MAXPOWER : 0; -} - -/************************************************************************************** - * Name: ug2864hsweg01_setpower - * - * Description: - * Enable/disable LCD panel power (0: full off - CONFIG_LCD_MAXPOWER: full on). On - * backlit LCDs, this setting may correspond to the backlight setting. - * - **************************************************************************************/ - -static int ug2864hsweg01_setpower(struct lcd_dev_s *dev, int power) -{ - struct ug2864hsweg01_dev_s *priv = (struct ug2864hsweg01_dev_s *)dev; - DEBUGASSERT(priv && (unsigned)power <= CONFIG_LCD_MAXPOWER && priv->spi); - - lcdvdbg("power: %d [%d]\n", power, priv->on ? CONFIG_LCD_MAXPOWER : 0); - - /* Lock and select device */ - - ug2864hsweg01_lock(priv->spi); - SPI_SELECT(priv->spi, SPIDEV_DISPLAY, true); - - if (power <= 0) - { - /* Turn the display off */ - - (void)SPI_SEND(priv->spi, SSD1306_DISPOFF); - priv->on = false; - } - else - { - /* Turn the display on */ - - (void)SPI_SEND(priv->spi, SSD1306_DISPON); /* Display on, dim mode */ - priv->on = true; - } - - /* De-select and unlock the device */ - - SPI_SELECT(priv->spi, SPIDEV_DISPLAY, false); - ug2864hsweg01_unlock(priv->spi); - return OK; -} - -/************************************************************************************** - * Name: ug2864hsweg01_getcontrast - * - * Description: - * Get the current contrast setting (0-CONFIG_LCD_MAXCONTRAST). - * - **************************************************************************************/ - -static int ug2864hsweg01_getcontrast(struct lcd_dev_s *dev) -{ - struct ug2864hsweg01_dev_s *priv = (struct ug2864hsweg01_dev_s *)dev; - DEBUGASSERT(priv); - - lcdvdbg("contrast: %d\n", priv->contrast); - return priv->contrast; -} - -/************************************************************************************** - * Name: ug2864hsweg01_setcontrast - * - * Description: - * Set LCD panel contrast (0-CONFIG_LCD_MAXCONTRAST). - * - **************************************************************************************/ - -static int ug2864hsweg01_setcontrast(struct lcd_dev_s *dev, unsigned int contrast) -{ - struct ug2864hsweg01_dev_s *priv = (struct ug2864hsweg01_dev_s *)dev; - unsigned int scaled; - - lcdvdbg("contrast: %d\n", contrast); - DEBUGASSERT(priv); - - /* Verify the contrast value */ - -#ifdef CONFIG_DEBUG - if (contrast > CONFIG_LCD_MAXCONTRAST) - { - return -EINVAL; - } -#endif - - /* Scale contrast: newcontrast = 255 * contrast / CONFIG_LCD_MAXCONTRAST - * Where contrast is in the range {1,255} - */ - -#if CONFIG_LCD_MAXCONTRAST != 255 - scaled = ((contrast << 8) - 1) / CONFIG_LCD_MAXCONTRAST; -#else - scaled = contrast; -#endif - - /* Lock and select device */ - - ug2864hsweg01_lock(priv->spi); - SPI_SELECT(priv->spi, SPIDEV_DISPLAY, true); - - /* Select command transfer */ - - SPI_CMDDATA(priv->spi, SPIDEV_DISPLAY, true); - - /* Set the contrast */ - - (void)SPI_SEND(priv->spi, SSD1306_CONTRAST_MODE); /* Set contrast control register */ - (void)SPI_SEND(priv->spi, SSD1306_CONTRAST(scaled)); /* Data 1: Set 1 of 256 contrast steps */ - priv->contrast = contrast; - - /* De-select and unlock the device */ - - SPI_SELECT(priv->spi, SPIDEV_DISPLAY, false); - ug2864hsweg01_unlock(priv->spi); - return OK; -} - -/************************************************************************************** - * Public Functions - **************************************************************************************/ - -/************************************************************************************** - * Name: ug2864hsweg01_initialize - * - * Description: - * Initialize the UG-2864HSWEG01 video hardware. The initial state of the - * OLED is fully initialized, display memory cleared, and the OLED ready - * to use, but with the power setting at 0 (full off == sleep mode). - * - * Input Parameters: - * - * spi - A reference to the SPI driver instance. - * devno - A value in the range of 0 through CONFIG_UG2864HSWEG01_NINTERFACES-1. - * This allows support for multiple OLED devices. - * - * Returned Value: - * - * On success, this function returns a reference to the LCD object for - * the specified OLED. NULL is returned on any failure. - * - **************************************************************************************/ - -FAR struct lcd_dev_s *ug2864hsweg01_initialize(FAR struct spi_dev_s *spi, unsigned int devno) -{ - FAR struct ug2864hsweg01_dev_s *priv = &g_oleddev; - - lcdvdbg("Initializing\n"); - DEBUGASSERT(spi && devno == 0); - - /* Save the reference to the SPI device */ - - priv->spi = spi; - - /* Configure the SPI */ - - ug2864hsweg01_configspi(spi); - - /* Lock and select device */ - - ug2864hsweg01_lock(priv->spi); - SPI_SELECT(spi, SPIDEV_DISPLAY, true); - - /* Select command transfer */ - - SPI_CMDDATA(spi, SPIDEV_DISPLAY, true); - - /* Configure OLED SPI or I/O, must be delayed 1-10ms */ - - up_mdelay(5); - - /* Configure the device */ - -//#define OLED_WriteCmd(v) SPI_SEND(spi,v) -// -// /* Module manufacturers to provide initialization code Ä£¿é³§¼ÒÌṩ³õʼ»¯´úÂë */ -// -// OLED_WriteCmd(0xAE); /* ¹Ø±ÕOLEDÃæ°åÏÔʾ(ÐÝÃß) */ -// OLED_WriteCmd(0x00); /* ÉèÖÃÁеØÖ·µÍ4bit */ -// OLED_WriteCmd(0x10); /* ÉèÖÃÁеØÖ·¸ß4bit */ -// OLED_WriteCmd(0x40); /* ÉèÖÃÆðʼÐеØÖ·£¨µÍ5bit 0-63£©£¬ Ó²¼þÏà¹Ø*/ -// -// OLED_WriteCmd(0x81); /* ÉèÖöԱȶÈÃüÁî(Ë«×Ö½ÚÃüÁ£¬µÚ1¸ö×Ö½ÚÊÇÃüÁµÚ2¸ö×Ö½ÚÊǶԱȶȲÎÊý0-255 */ -// OLED_WriteCmd(0xCF); /* ÉèÖöԱȶȲÎÊý */ -// -// OLED_WriteCmd(0xA1); /* A0 £ºÁеØÖ·0Ó³Éäµ½SEG0; A1 £ºÁеØÖ·127Ó³Éäµ½SEG0 */ -// OLED_WriteCmd(0xA6); /* A6 : ÉèÖÃÕý³£ÏÔʾģʽ; A7 : ÉèÖÃΪ·´ÏÔģʽ */ -// -// OLED_WriteCmd(0xA8); /* ÉèÖÃCOM·Êý */ -// OLED_WriteCmd(0x3F); /* 1 ->£¨63+1£©Â· */ -// -// OLED_WriteCmd(0xD3); /* ÉèÖÃÏÔʾƫÒÆ£¨Ë«×Ö½ÚÃüÁ*/ -// OLED_WriteCmd(0x00); /* ÎÞÆ«ÒÆ */ -// -// OLED_WriteCmd(0xD5); /* ÉèÖÃÏÔʾʱÖÓ·ÖƵϵÊý/Õñµ´ÆµÂÊ */ -// OLED_WriteCmd(0x80); /* ÉèÖ÷ÖƵϵÊý,¸ß4bitÊÇ·ÖƵϵÊý£¬µÍ4bitÊÇÕñµ´ÆµÂÊ */ -// -// OLED_WriteCmd(0xD9); /* ÉèÖÃÔ¤³äµçÖÜÆÚ */ -// OLED_WriteCmd(0xF1); /* [3:0],PHASE 1; [7:4],PHASE 2; */ -// -// OLED_WriteCmd(0xDA); /* ÉèÖÃCOM½ÅÓ²¼þ½ÓÏß·½Ê½ */ -// OLED_WriteCmd(0x12); -// -// OLED_WriteCmd(0xDB); /* ÉèÖà vcomh µçѹ±¶ÂÊ */ -// OLED_WriteCmd(0x40); /* [6:4] 000 = 0.65 x VCC; 0.77 x VCC (RESET); 0.83 x VCC */ -// -// OLED_WriteCmd(0x8D); /* ÉèÖóäµç±Ã£¨ºÍϸöÃüÁî½áºÏʹÓã© */ -// OLED_WriteCmd(0x14); /* 0x14 ʹÄܳäµç±Ã£¬ 0x10 ÊÇ¹Ø±Õ */ -// OLED_WriteCmd(0xAF); /* ´ò¿ªOLEDÃæ°å */ - - SPI_SEND(spi, SSD1306_DISPOFF); /* Display off 0xAE*/ - SPI_SEND(spi, SSD1306_SETCOLL(0)); /* Set lower column address 0x00 */ - SPI_SEND(spi, SSD1306_SETCOLH(0)); /* Set higher column address 0x10 */ - SPI_SEND(spi, SSD1306_STARTLINE(0)); /* Set display start line 0x40*/ - /* SPI_SEND(spi, SSD1306_PAGEADDR(0));*//* Set page address (Can ignore)*/ - SPI_SEND(spi, SSD1306_CONTRAST_MODE); /* Contrast control 0x81*/ - SPI_SEND(spi ,SSD1306_CONTRAST(UG2864HSWEG01_CONTRAST)); /* Default contrast 0xCF */ - SPI_SEND(spi, SSD1306_REMAPPLEFT); /* Set segment remap left 95 to 0 | 0xA1*/ - /* SPI_SEND(spi, SSD1306_EDISPOFF); */ /* Normal display :off 0xA4 (Can ignore)*/ - SPI_SEND(spi, SSD1306_NORMAL); /* Normal (un-reversed) display mode 0xA6 */ - SPI_SEND(spi, SSD1306_MRATIO_MODE); /* Multiplex ratio 0xA8*/ - SPI_SEND(spi, SSD1306_MRATIO(0x3f)); /* Duty = 1/64 */ - /* SPI_SEND(spi, SSD1306_SCANTOCOM0);*/ /* Com scan direction: Scan from COM[n-1] to COM[0] (Can ignore)*/ - SPI_SEND(spi, SSD1306_DISPOFFS_MODE); /* Set display offset 0xD3 */ - SPI_SEND(spi, SSD1306_DISPOFFS(0)); - SPI_SEND(spi, SSD1306_CLKDIV_SET); /* Set clock divider 0xD5*/ - SPI_SEND(spi, SSD1306_CLKDIV(8,0)); /* 0x80*/ - - SPI_SEND(spi, SSD1306_CHRGPER_SET); /* ++Set pre-charge period 0xD9*/ - SPI_SEND(spi, SSD1306_CHRGPER(0x0f,1)); /* 0xf1 or 0x22£¨Enhanced mode?£© */ - - SPI_SEND(spi, SSD1306_CMNPAD_CONFIG); /* Set common pads / set com pins hardware configuration 0xDA*/ - SPI_SEND(spi, SSD1306_CMNPAD(0x12)); /* 0x12 */ - - SPI_SEND(spi, SSD1306_VCOM_SET); /* set vcomh 0xDB*/ - SPI_SEND(spi, SSD1306_VCOM(0x40)); - - SPI_SEND(spi, SSD1306_CHRPUMP_SET); /* ++Set Charge Pump enable/disable 0x8D ssd1306*/ - SPI_SEND(spi, SSD1306_CHRPUMP_ON); /* 0x14 close 0x10 */ - - /*SPI_SEND(spi, SSD1306_DCDC_MODE); */ /* DC/DC control mode: on (SSD1306 Not supported) */ - /*SPI_SEND(spi, SSD1306_DCDC_ON); */ - - SPI_SEND(spi, SSD1306_DISPON); /* display ON 0xAF */ - - /* De-select and unlock the device */ - - SPI_SELECT(spi, SPIDEV_DISPLAY, false); - ug2864hsweg01_unlock(priv->spi); - - /* Clear the display */ - - up_mdelay(100); - ug2864hsweg01_fill(&priv->dev, UG_Y1_BLACK); - return &priv->dev; -} - -/************************************************************************************** - * Name: ug2864hsweg01_fill - * - * Description: - * This non-standard method can be used to clear the entire display by writing one - * color to the display. This is much faster than writing a series of runs. - * - * Input Parameters: - * priv - Reference to private driver structure - * - * Assumptions: - * Caller has selected the OLED section. - * - **************************************************************************************/ - -void ug2864hsweg01_fill(FAR struct lcd_dev_s *dev, uint8_t color) -{ - FAR struct ug2864hsweg01_dev_s *priv = &g_oleddev; - unsigned int page; - - /* Make an 8-bit version of the selected color */ - - if (color & 1) - { - color = 0xff; - } - else - { - color = 0; - } - - /* Initialize the framebuffer */ - - memset(priv->fb, color, UG2864HSWEG01_FBSIZE); - - /* Lock and select device */ - - ug2864hsweg01_lock(priv->spi); - SPI_SELECT(priv->spi, SPIDEV_DISPLAY, true); - - /* Visit each page */ - - for (page = 0; page < UG2864HSWEG01_DEV_PAGES; page++) - { - /* Select command transfer */ - - SPI_CMDDATA(priv->spi, SPIDEV_DISPLAY, true); - - /* Set the column address to the XOFFSET value */ - - SPI_SEND(priv->spi, SSD1306_SETCOLL(UG2864HSWEG01_DEV_XOFFSET)); - SPI_SEND(priv->spi, SSD1306_SETCOLH(0)); - - /* Set the page address */ - - SPI_SEND(priv->spi, SSD1306_PAGEADDR(page)); - - /* Select data transfer */ - - SPI_CMDDATA(priv->spi, SPIDEV_DISPLAY, false); - - /* Transfer one page of the selected color */ - - (void)SPI_SNDBLOCK(priv->spi, &priv->fb[page * UG2864HSWEG01_XRES], - UG2864HSWEG01_XRES); - } - - /* De-select and unlock the device */ - - SPI_SELECT(priv->spi, SPIDEV_DISPLAY, false); - ug2864hsweg01_unlock(priv->spi); -} - -#endif /* CONFIG_LCD_UG2864HSWEG01 */ diff --git a/nuttx/drivers/lcd/ug-9664hswag01.c b/nuttx/drivers/lcd/ug-9664hswag01.c deleted file mode 100644 index 6ef78fca6..000000000 --- a/nuttx/drivers/lcd/ug-9664hswag01.c +++ /dev/null @@ -1,1046 +0,0 @@ -/************************************************************************************** - * drivers/lcd/ug-9664hswag01.c - * Driver for the Univision UG-9664HSWAG01 Display with the Solomon Systech SSD1305 LCD - * controller. - * - * Copyright (C) 2011 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt <gnutt@nuttx.org> - * - * Reference: "Product Specification, OEL Display Module, UG-9664HSWAG01", Univision - * Technology Inc., SAS1-6020-B, January 3, 2008. - * - * 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 written 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. - * - **************************************************************************************/ - -/************************************************************************************** - * Included Files - **************************************************************************************/ - -#include <nuttx/config.h> - -#include <sys/types.h> -#include <stdint.h> -#include <stdbool.h> -#include <string.h> -#include <errno.h> -#include <debug.h> - -#include <nuttx/arch.h> -#include <nuttx/spi.h> -#include <nuttx/lcd/lcd.h> -#include <nuttx/lcd/ug-9664hswag01.h> - -#include "ssd1305.h" - -/************************************************************************************** - * Pre-processor Definitions - **************************************************************************************/ - -/* Configuration **********************************************************************/ -/* UG-9664HSWAG01 Configuration Settings: - * - * CONFIG_UG9664HSWAG01_SPIMODE - Controls the SPI mode - * CONFIG_UG9664HSWAG01_FREQUENCY - Define to use a different bus frequency - * CONFIG_UG9664HSWAG01_NINTERFACES - Specifies the number of physical - * UG-9664HSWAG01 devices that will be supported. NOTE: At present, this - * must be undefined or defined to be 1. - * CONFIG_UG9664HSWAG01_POWER - * If the hardware supports a controllable OLED a power supply, this - * configuration shold be defined. (See ug_power() below). - * - * Required LCD driver settings: - * CONFIG_LCD_UG9664HSWAG01 - Enable UG-9664HSWAG01 support - * CONFIG_LCD_MAXCONTRAST should be 255, but any value >0 and <=255 will be accepted. - * CONFIG_LCD_MAXPOWER should be 2: 0=off, 1=dim, 2=normal - * - * Required SPI driver settings: - * CONFIG_SPI_CMDDATA - Include support for cmd/data selection. - */ - -/* Verify that all configuration requirements have been met */ - -/* The UG-9664HSWAG01 spec says that is supports SPI mode 0,0 only. However, somtimes - * you need to tinker with these things. - */ - -#ifndef CONFIG_UG9664HSWAG01_SPIMODE -# define CONFIG_UG9664HSWAG01_SPIMODE SPIDEV_MODE0 -#endif - -/* SPI frequency */ - -#ifndef CONFIG_UG9664HSWAG01_FREQUENCY -# define CONFIG_UG9664HSWAG01_FREQUENCY 3500000 -#endif - -/* CONFIG_UG9664HSWAG01_NINTERFACES determines the number of physical interfaces - * that will be supported. - */ - -#ifndef CONFIG_UG9664HSWAG01_NINTERFACES -# define CONFIG_UG9664HSWAG01_NINTERFACES 1 -#endif - -#if CONFIG_UG9664HSWAG01_NINTERFACES != 1 -# warning "Only a single UG-9664HSWAG01 interface is supported" -# undef CONFIG_UG9664HSWAG01_NINTERFACES -# define CONFIG_UG9664HSWAG01_NINTERFACES 1 -#endif - -/* Verbose debug must also be enabled to use the extra OLED debug */ - -#ifndef CONFIG_DEBUG -# undef CONFIG_DEBUG_VERBOSE -#endif - -#ifndef CONFIG_DEBUG_VERBOSE -# undef CONFIG_DEBUG_LCD -#endif - -/* Check contrast selection */ - -#ifndef CONFIG_LCD_MAXCONTRAST -# define CONFIG_LCD_MAXCONTRAST 255 -#endif - -#if CONFIG_LCD_MAXCONTRAST <= 0 || CONFIG_LCD_MAXCONTRAST > 255 -# error "CONFIG_LCD_MAXCONTRAST exceeds supported maximum" -#endif - -#if CONFIG_LCD_MAXCONTRAST < 255 -# warning "Optimal setting of CONFIG_LCD_MAXCONTRAST is 255" -#endif - -/* Check power setting */ - -#if !defined(CONFIG_LCD_MAXPOWER) -# define CONFIG_LCD_MAXPOWER 2 -#endif - -#if CONFIG_LCD_MAXPOWER != 2 -# warning "CONFIG_LCD_MAXPOWER should be 2" -# undef CONFIG_LCD_MAXPOWER -# define CONFIG_LCD_MAXPOWER 2 -#endif - -/* The OLED requires CMD/DATA SPI support */ - -#ifndef CONFIG_SPI_CMDDATA -# error "CONFIG_SPI_CMDDATA must be defined in your NuttX configuration" -#endif - -/* Color is 1bpp monochrome with leftmost column contained in bits 0 */ - -#ifdef CONFIG_NX_DISABLE_1BPP -# warning "1 bit-per-pixel support needed" -#endif - -/* Color Properties *******************************************************************/ -/* The SSD1305 display controller can handle a resolution of 132x64. The OLED - * on the base board is 96x64. - */ - -#define UG_DEV_XRES 132 -#define UG_XOFFSET 18 - -/* Display Resolution */ - -#define UG_XRES 96 -#define UG_YRES 64 - -/* Color depth and format */ - -#define UG_BPP 1 -#define UG_COLORFMT FB_FMT_Y1 - -/* Bytes per logical row and actual device row */ - -#define UG_XSTRIDE (UG_XRES >> 3) /* Pixels arrange "horizontally for user" */ -#define UG_YSTRIDE (UG_YRES >> 3) /* But actual device arrangement is "vertical" */ - -/* The size of the shadow frame buffer */ - -#define UG_FBSIZE (UG_XRES * UG_YSTRIDE) - -/* Bit helpers */ - -#define LS_BIT (1 << 0) -#define MS_BIT (1 << 7) - -/* Debug ******************************************************************************/ - -#ifdef CONFIG_DEBUG_LCD -# define lcddbg(format, arg...) vdbg(format, ##arg) -#else -# define lcddbg(x...) -#endif - -/************************************************************************************** - * Private Type Definition - **************************************************************************************/ - -/* This structure describes the state of this driver */ - -struct ug_dev_s -{ - /* Publically visible device structure */ - - struct lcd_dev_s dev; - - /* Private LCD-specific information follows */ - - FAR struct spi_dev_s *spi; - uint8_t contrast; - uint8_t powered; - - /* The SSD1305 does not support reading from the display memory in SPI mode. - * Since there is 1 BPP and access is byte-by-byte, it is necessary to keep - * a shadow copy of the framebuffer memory. - */ - - uint8_t fb[UG_FBSIZE]; -}; - -/************************************************************************************** - * Private Function Protototypes - **************************************************************************************/ - -/* SPI helpers */ - -#ifdef CONFIG_SPI_OWNBUS -static inline void ug_select(FAR struct spi_dev_s *spi); -static inline void ug_deselect(FAR struct spi_dev_s *spi); -#else -static void ug_select(FAR struct spi_dev_s *spi); -static void ug_deselect(FAR struct spi_dev_s *spi); -#endif - -/* LCD Data Transfer Methods */ - -static int ug_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer, - size_t npixels); -static int ug_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer, - size_t npixels); - -/* LCD Configuration */ - -static int ug_getvideoinfo(FAR struct lcd_dev_s *dev, - FAR struct fb_videoinfo_s *vinfo); -static int ug_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planeno, - FAR struct lcd_planeinfo_s *pinfo); - -/* LCD RGB Mapping */ - -#ifdef CONFIG_FB_CMAP -# error "RGB color mapping not supported by this driver" -#endif - -/* Cursor Controls */ - -#ifdef CONFIG_FB_HWCURSOR -# error "Cursor control not supported by this driver" -#endif - -/* LCD Specific Controls */ - -static int ug_getpower(struct lcd_dev_s *dev); -static int ug_setpower(struct lcd_dev_s *dev, int power); -static int ug_getcontrast(struct lcd_dev_s *dev); -static int ug_setcontrast(struct lcd_dev_s *dev, unsigned int contrast); - -/* Initialization */ - -static inline void up_clear(FAR struct ug_dev_s *priv); - -/************************************************************************************** - * Private Data - **************************************************************************************/ - -/* This is working memory allocated by the LCD driver for each LCD device - * and for each color plane. This memory will hold one raster line of data. - * The size of the allocated run buffer must therefore be at least - * (bpp * xres / 8). Actual alignment of the buffer must conform to the - * bitwidth of the underlying pixel type. - * - * If there are multiple planes, they may share the same working buffer - * because different planes will not be operate on concurrently. However, - * if there are multiple LCD devices, they must each have unique run buffers. - */ - -static uint8_t g_runbuffer[UG_XSTRIDE+1]; - -/* This structure describes the overall LCD video controller */ - -static const struct fb_videoinfo_s g_videoinfo = -{ - .fmt = UG_COLORFMT, /* Color format: RGB16-565: RRRR RGGG GGGB BBBB */ - .xres = UG_XRES, /* Horizontal resolution in pixel columns */ - .yres = UG_YRES, /* Vertical resolution in pixel rows */ - .nplanes = 1, /* Number of color planes supported */ -}; - -/* This is the standard, NuttX Plane information object */ - -static const struct lcd_planeinfo_s g_planeinfo = -{ - .putrun = ug_putrun, /* Put a run into LCD memory */ - .getrun = ug_getrun, /* Get a run from LCD memory */ - .buffer = (uint8_t*)g_runbuffer, /* Run scratch buffer */ - .bpp = UG_BPP, /* Bits-per-pixel */ -}; - -/* This is the standard, NuttX LCD driver object */ - -static struct ug_dev_s g_ugdev = -{ - .dev = - { - /* LCD Configuration */ - - .getvideoinfo = ug_getvideoinfo, - .getplaneinfo = ug_getplaneinfo, - - /* LCD RGB Mapping -- Not supported */ - /* Cursor Controls -- Not supported */ - - /* LCD Specific Controls */ - - .getpower = ug_getpower, - .setpower = ug_setpower, - .getcontrast = ug_getcontrast, - .setcontrast = ug_setcontrast, - }, -}; - -/************************************************************************************** - * Private Functions - **************************************************************************************/ - -/************************************************************************************** - * Name: ug_powerstring - * - * Description: - * Convert the power setting to a string. - * - **************************************************************************************/ - - -static inline FAR const char *ug_powerstring(uint8_t power) -{ - if (power == UG_POWER_OFF) - { - return "OFF"; - } - else if (power == UG_POWER_DIM) - { - return "DIM"; - } - else if (power == UG_POWER_ON) - { - return "ON"; - } - else - { - return "ERROR"; - } -} - -/************************************************************************************** - * Function: ug_select - * - * Description: - * Select the SPI, locking and re-configuring if necessary - * - * Parameters: - * spi - Reference to the SPI driver structure - * - * Returned Value: - * None - * - * Assumptions: - * - **************************************************************************************/ - -#ifdef CONFIG_SPI_OWNBUS -static inline void ug_select(FAR struct spi_dev_s *spi) -{ - /* We own the SPI bus, so just select the chip */ - - SPI_SELECT(spi, SPIDEV_DISPLAY, true); -} -#else -static void ug_select(FAR struct spi_dev_s *spi) -{ - /* Select UG-9664HSWAG01 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, true); - - /* Now make sure that the SPI bus is configured for the UG-9664HSWAG01 (it - * might have gotten configured for a different device while unlocked) - */ - - SPI_SETMODE(spi, CONFIG_UG9664HSWAG01_SPIMODE); - SPI_SETBITS(spi, 8); -#ifdef CONFIG_UG9664HSWAG01_FREQUENCY - SPI_SETFREQUENCY(spi, CONFIG_UG9664HSWAG01_FREQUENCY); -#endif -} -#endif - -/************************************************************************************** - * Function: ug_deselect - * - * Description: - * De-select the SPI - * - * Parameters: - * spi - Reference to the SPI driver structure - * - * Returned Value: - * None - * - * Assumptions: - * - **************************************************************************************/ - -#ifdef CONFIG_SPI_OWNBUS -static inline void ug_deselect(FAR struct spi_dev_s *spi) -{ - /* We own the SPI bus, so just de-select the chip */ - - SPI_SELECT(spi, SPIDEV_DISPLAY, false); -} -#else -static void ug_deselect(FAR struct spi_dev_s *spi) -{ - /* De-select UG-9664HSWAG01 chip and relinquish the SPI bus. */ - - SPI_SELECT(spi, SPIDEV_DISPLAY, false); - SPI_LOCK(spi, false); -} -#endif - -/************************************************************************************** - * Name: ug_putrun - * - * Description: - * This method can be used to write a partial raster line to the LCD: - * - * row - Starting row to write to (range: 0 <= row < yres) - * col - Starting column to write to (range: 0 <= col <= xres-npixels) - * buffer - The buffer containing the run to be written to the LCD - * npixels - The number of pixels to write to the LCD - * (range: 0 < npixels <= xres-col) - * - **************************************************************************************/ - -static int ug_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer, - size_t npixels) -{ - /* Because of this line of code, we will only be able to support a single UG device */ - - FAR struct ug_dev_s *priv = &g_ugdev; - FAR uint8_t *fbptr; - FAR uint8_t *ptr; - uint8_t devcol; - uint8_t fbmask; - uint8_t page; - uint8_t usrmask; - uint8_t i; - int pixlen; - - gvdbg("row: %d col: %d npixels: %d\n", row, col, npixels); - DEBUGASSERT(buffer); - - /* Clip the run to the display */ - - pixlen = npixels; - if ((unsigned int)col + (unsigned int)pixlen > (unsigned int)UG_XRES) - { - pixlen = (int)UG_XRES - (int)col; - } - - /* Verify that some portion of the run remains on the display */ - - if (pixlen <= 0 || row > UG_YRES) - { - return OK; - } - - /* Get the page number. The range of 64 lines is divided up into eight - * pages of 8 lines each. - */ - - page = row >> 3; - - /* Update the shadow frame buffer memory. First determine the pixel - * position in the frame buffer memory. Pixels are organized like - * this: - * - * --------+---+---+---+---+-...-+-----+ - * Segment | 0 | 1 | 2 | 3 | ... | 131 | - * --------+---+---+---+---+-...-+-----+ - * Bit 0 | | X | | | | | - * Bit 1 | | X | | | | | - * Bit 2 | | X | | | | | - * Bit 3 | | X | | | | | - * Bit 4 | | X | | | | | - * Bit 5 | | X | | | | | - * Bit 6 | | X | | | | | - * Bit 7 | | X | | | | | - * --------+---+---+---+---+-...-+-----+ - * - * So, in order to draw a white, horizontal line, at row 45. we - * would have to modify all of the bytes in page 45/8 = 5. We - * would have to set bit 45%8 = 5 in every byte in the page. - */ - - fbmask = 1 << (row & 7); - fbptr = &priv->fb[page * UG_XRES + col]; - ptr = fbptr; -#ifdef CONFIG_NX_PACKEDMSFIRST - usrmask = MS_BIT; -#else - usrmask = LS_BIT; -#endif - - for (i = 0; i < pixlen; i++) - { - /* Set or clear the corresponding bit */ - - if ((*buffer & usrmask) != 0) - { - *ptr++ |= fbmask; - } - else - { - *ptr++ &= ~fbmask; - } - - /* Inc/Decrement to the next source pixel */ - -#ifdef CONFIG_NX_PACKEDMSFIRST - if (usrmask == LS_BIT) - { - buffer++; - usrmask = MS_BIT; - } - else - { - usrmask >>= 1; - } -#else - if (usrmask == MS_BIT) - { - buffer++; - usrmask = LS_BIT; - } - else - { - usrmask <<= 1; - } -#endif - } - - /* Offset the column position to account for smaller horizontal - * display range. - */ - - devcol = col + UG_XOFFSET; - - /* Select and lock the device */ - - ug_select(priv->spi); - - /* Select command transfer */ - - SPI_CMDDATA(priv->spi, SPIDEV_DISPLAY, true); - - /* Set the starting position for the run */ - - (void)SPI_SEND(priv->spi, SSD1305_SETPAGESTART+page); /* Set the page start */ - (void)SPI_SEND(priv->spi, SSD1305_SETCOLL + (devcol & 0x0f)); /* Set the low column */ - (void)SPI_SEND(priv->spi, SSD1305_SETCOLH + (devcol >> 4)); /* Set the high column */ - - /* Select data transfer */ - - SPI_CMDDATA(priv->spi, SPIDEV_DISPLAY, false); - - /* Then transfer all of the data */ - - (void)SPI_SNDBLOCK(priv->spi, fbptr, pixlen); - - /* Unlock and de-select the device */ - - ug_deselect(priv->spi); - return OK; -} - -/************************************************************************************** - * Name: ug_getrun - * - * Description: - * This method can be used to read a partial raster line from the LCD: - * - * 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) - * - **************************************************************************************/ - -static int ug_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer, - size_t npixels) -{ - /* Because of this line of code, we will only be able to support a single UG device */ - - FAR struct ug_dev_s *priv = &g_ugdev; - FAR uint8_t *fbptr; - uint8_t page; - uint8_t fbmask; - uint8_t usrmask; - uint8_t i; - int pixlen; - - gvdbg("row: %d col: %d npixels: %d\n", row, col, npixels); - DEBUGASSERT(buffer); - - /* Clip the run to the display */ - - pixlen = npixels; - if ((unsigned int)col + (unsigned int)pixlen > (unsigned int)UG_XRES) - { - pixlen = (int)UG_XRES - (int)col; - } - - /* Verify that some portion of the run is actually the display */ - - if (pixlen <= 0 || row > UG_YRES) - { - return -EINVAL; - } - - /* Then transfer the display data from the shadow frame buffer memory */ - /* Get the page number. The range of 64 lines is divided up into eight - * pages of 8 lines each. - */ - - page = row >> 3; - - /* Update the shadow frame buffer memory. First determine the pixel - * position in the frame buffer memory. Pixels are organized like - * this: - * - * --------+---+---+---+---+-...-+-----+ - * Segment | 0 | 1 | 2 | 3 | ... | 131 | - * --------+---+---+---+---+-...-+-----+ - * Bit 0 | | X | | | | | - * Bit 1 | | X | | | | | - * Bit 2 | | X | | | | | - * Bit 3 | | X | | | | | - * Bit 4 | | X | | | | | - * Bit 5 | | X | | | | | - * Bit 6 | | X | | | | | - * Bit 7 | | X | | | | | - * --------+---+---+---+---+-...-+-----+ - * - * So, in order to draw a white, horizontal line, at row 45. we - * would have to modify all of the bytes in page 45/8 = 5. We - * would have to set bit 45%8 = 5 in every byte in the page. - */ - - fbmask = 1 << (row & 7); - fbptr = &priv->fb[page * UG_XRES + col]; -#ifdef CONFIG_NX_PACKEDMSFIRST - usrmask = MS_BIT; -#else - usrmask = LS_BIT; -#endif - - *buffer = 0; - for (i = 0; i < pixlen; i++) - { - /* Set or clear the corresponding bit */ - - uint8_t byte = *fbptr++; - if ((byte & fbmask) != 0) - { - *buffer |= usrmask; - } - - /* Inc/Decrement to the next destination pixel. Hmmmm. It looks like - * this logic could write past the end of the user buffer. Revisit - * this! - */ - -#ifdef CONFIG_NX_PACKEDMSFIRST - if (usrmask == LS_BIT) - { - buffer++; - *buffer = 0; - usrmask = MS_BIT; - } - else - { - usrmask >>= 1; - } -#else - if (usrmask == MS_BIT) - { - buffer++; - *buffer = 0; - usrmask = LS_BIT; - } - else - { - usrmask <<= 1; - } -#endif - } - - return OK; -} - -/************************************************************************************** - * Name: ug_getvideoinfo - * - * Description: - * Get information about the LCD video controller configuration. - * - **************************************************************************************/ - -static int ug_getvideoinfo(FAR struct lcd_dev_s *dev, - FAR struct fb_videoinfo_s *vinfo) -{ - DEBUGASSERT(dev && vinfo); - gvdbg("fmt: %d xres: %d yres: %d nplanes: %d\n", - g_videoinfo.fmt, g_videoinfo.xres, g_videoinfo.yres, g_videoinfo.nplanes); - memcpy(vinfo, &g_videoinfo, sizeof(struct fb_videoinfo_s)); - return OK; -} - -/************************************************************************************** - * Name: ug_getplaneinfo - * - * Description: - * Get information about the configuration of each LCD color plane. - * - **************************************************************************************/ - -static int ug_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planeno, - FAR struct lcd_planeinfo_s *pinfo) -{ - DEBUGASSERT(dev && pinfo && planeno == 0); - gvdbg("planeno: %d bpp: %d\n", planeno, g_planeinfo.bpp); - memcpy(pinfo, &g_planeinfo, sizeof(struct lcd_planeinfo_s)); - return OK; -} - -/************************************************************************************** - * Name: ug_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. - * - **************************************************************************************/ - -static int ug_getpower(struct lcd_dev_s *dev) -{ - struct ug_dev_s *priv = (struct ug_dev_s *)dev; - DEBUGASSERT(priv); - gvdbg("powered: %s\n", ug_powerstring(priv->powered)); - return priv->powered; -} - -/************************************************************************************** - * Name: ug_setpower - * - * Description: - * Enable/disable LCD panel power (0: full off - CONFIG_LCD_MAXPOWER: full on). On - * backlit LCDs, this setting may correspond to the backlight setting. - * - **************************************************************************************/ - -static int ug_setpower(struct lcd_dev_s *dev, int power) -{ - struct ug_dev_s *priv = (struct ug_dev_s *)dev; - - DEBUGASSERT(priv && (unsigned)power <= CONFIG_LCD_MAXPOWER); - gvdbg("power: %s powered: %s\n", - ug_powerstring(power), ug_powerstring(priv->powered)); - - /* Select and lock the device */ - - ug_select(priv->spi); - if (power <= UG_POWER_OFF) - { - /* Turn the display off */ - - (void)SPI_SEND(priv->spi, SSD1305_DISPOFF); /* Display off */ - - /* Remove power to the device */ - - ug_power(0, false); - priv->powered = UG_POWER_OFF; - } - else - { - /* Turn the display on, dim or normal */ - - if (power == UG_POWER_DIM) - { - (void)SPI_SEND(priv->spi, SSD1305_DISPONDIM); /* Display on, dim mode */ - } - else /* if (power > UG_POWER_DIM) */ - { - (void)SPI_SEND(priv->spi, SSD1305_DISPON); /* Display on, normal mode */ - power = UG_POWER_ON; - } - (void)SPI_SEND(priv->spi, SSD1305_DISPRAM); /* Resume to RAM content display */ - - /* Restore power to the device */ - - ug_power(0, true); - priv->powered = power; - } - ug_deselect(priv->spi); - - return OK; -} - -/************************************************************************************** - * Name: ug_getcontrast - * - * Description: - * Get the current contrast setting (0-CONFIG_LCD_MAXCONTRAST). - * - **************************************************************************************/ - -static int ug_getcontrast(struct lcd_dev_s *dev) -{ - struct ug_dev_s *priv = (struct ug_dev_s *)dev; - DEBUGASSERT(priv); - return (int)priv->contrast; -} - -/************************************************************************************** - * Name: ug_setcontrast - * - * Description: - * Set LCD panel contrast (0-CONFIG_LCD_MAXCONTRAST). - * - **************************************************************************************/ - -static int ug_setcontrast(struct lcd_dev_s *dev, unsigned int contrast) -{ - struct ug_dev_s *priv = (struct ug_dev_s *)dev; - - gvdbg("contrast: %d\n", contrast); - DEBUGASSERT(priv); - - if (contrast > 255) - { - return -EINVAL; - } - - /* Select and lock the device */ - - ug_select(priv->spi); - - /* Select command transfer */ - - SPI_CMDDATA(priv->spi, SPIDEV_DISPLAY, true); - - /* Set the contrast */ - - (void)SPI_SEND(priv->spi, SSD1305_SETCONTRAST); /* Set contrast control register */ - (void)SPI_SEND(priv->spi, contrast); /* Data 1: Set 1 of 256 contrast steps */ - priv->contrast = contrast; - - /* Unlock and de-select the device */ - - ug_deselect(priv->spi); - return OK; -} - -/************************************************************************************** - * Name: up_clear - * - * Description: - * Clear the display. - * - **************************************************************************************/ - -static inline void up_clear(FAR struct ug_dev_s *priv) -{ - FAR struct spi_dev_s *spi = priv->spi; - int page; - int i; - - /* Clear the framebuffer */ - - memset(priv->fb, UG_Y1_BLACK, UG_FBSIZE); - - /* Select and lock the device */ - - ug_select(priv->spi); - - /* Go through all 8 pages */ - - for (page = 0, i = 0; i < 8; i++) - { - /* Select command transfer */ - - SPI_CMDDATA(spi, SPIDEV_DISPLAY, true); - - /* Set the starting position for the run */ - - (void)SPI_SEND(priv->spi, SSD1305_SETPAGESTART+i); - (void)SPI_SEND(priv->spi, SSD1305_SETCOLL + (UG_XOFFSET & 0x0f)); - (void)SPI_SEND(priv->spi, SSD1305_SETCOLH + (UG_XOFFSET >> 4)); - - /* Select data transfer */ - - SPI_CMDDATA(spi, SPIDEV_DISPLAY, false); - - /* Then transfer all 96 columns of data */ - - (void)SPI_SNDBLOCK(priv->spi, &priv->fb[page * UG_XRES], UG_XRES); - } - - /* Unlock and de-select the device */ - - ug_deselect(spi); -} - -/************************************************************************************** - * Public Functions - **************************************************************************************/ - -/************************************************************************************** - * Name: ug_initialize - * - * Description: - * Initialize the UG-9664HSWAG01 video hardware. The initial state of the - * OLED is fully initialized, display memory cleared, and the OLED ready to - * use, but with the power setting at 0 (full off == sleep mode). - * - * Input Parameters: - * - * spi - A reference to the SPI driver instance. - * devno - A value in the range of 0 through CONFIG_UG9664HSWAG01_NINTERFACES-1. - * This allows support for multiple OLED devices. - * - * Returned Value: - * - * On success, this function returns a reference to the LCD object for the specified - * OLED. NULL is returned on any failure. - * - **************************************************************************************/ - -FAR struct lcd_dev_s *ug_initialize(FAR struct spi_dev_s *spi, unsigned int devno) -{ - /* Configure and enable LCD */ - - FAR struct ug_dev_s *priv = &g_ugdev; - - gvdbg("Initializing\n"); - DEBUGASSERT(spi && devno == 0); - - /* Save the reference to the SPI device */ - - priv->spi = spi; - - /* Select and lock the device */ - - ug_select(spi); - - /* Make sure that the OLED off */ - - ug_power(0, false); - - /* Select command transfer */ - - SPI_CMDDATA(spi, SPIDEV_DISPLAY, true); - - /* Configure the device */ - - (void)SPI_SEND(spi, SSD1305_SETCOLL + 2); /* Set low column address */ - (void)SPI_SEND(spi, SSD1305_SETCOLH + 2); /* Set high column address */ - (void)SPI_SEND(spi, SSD1305_SETSTARTLINE+0); /* Display start set */ - (void)SPI_SEND(spi, SSD1305_SCROLL_STOP); /* Stop horizontal scroll */ - (void)SPI_SEND(spi, SSD1305_SETCONTRAST); /* Set contrast control register */ - (void)SPI_SEND(spi, 0x32); /* Data 1: Set 1 of 256 contrast steps */ - (void)SPI_SEND(spi, SSD1305_SETBRIGHTNESS); /* Brightness for color bank */ - (void)SPI_SEND(spi, 0x80); /* Data 1: Set 1 of 256 contrast steps */ - (void)SPI_SEND(spi, SSD1305_MAPCOL131); /* Set segment re-map */ - (void)SPI_SEND(spi, SSD1305_DISPNORMAL); /* Set normal display */ -/*(void)SPI_SEND(spi, SSD1305_DISPINVERTED); Set inverse display */ - (void)SPI_SEND(spi, SSD1305_SETMUX); /* Set multiplex ratio */ - (void)SPI_SEND(spi, 0x3f); /* Data 1: MUX ratio -1: 15-63 */ - (void)SPI_SEND(spi, SSD1305_SETOFFSET); /* Set display offset */ - (void)SPI_SEND(spi, 0x40); /* Data 1: Vertical shift by COM: 0-63 */ - (void)SPI_SEND(spi, SSD1305_MSTRCONFIG); /* Set dc-dc on/off */ - (void)SPI_SEND(spi, SSD1305_MSTRCONFIG_EXTVCC); /* Data 1: Select external Vcc */ - (void)SPI_SEND(spi, SSD1305_SETCOMREMAPPED); /* Set com output scan direction */ - (void)SPI_SEND(spi, SSD1305_SETDCLK); /* Set display clock divide - * ratio/oscillator/frequency */ - (void)SPI_SEND(spi, 15 << SSD1305_DCLKFREQ_SHIFT | 0 << SSD1305_DCLKDIV_SHIFT); - (void)SPI_SEND(spi, SSD1305_SETCOLORMODE); /* Set area color mode on/off & low power - * display mode */ - (void)SPI_SEND(spi, SSD1305_COLORMODE_MONO | SSD1305_POWERMODE_LOW); - (void)SPI_SEND(spi, SSD1305_SETPRECHARGE); /* Set pre-charge period */ - (void)SPI_SEND(spi, 15 << SSD1305_PHASE2_SHIFT | 1 << SSD1305_PHASE1_SHIFT); - (void)SPI_SEND(spi, SSD1305_SETCOMCONFIG); /* Set COM configuration */ - (void)SPI_SEND(spi, SSD1305_COMCONFIG_ALT); /* Data 1, Bit 4: 1=Alternative COM pin configuration */ - (void)SPI_SEND(spi, SSD1305_SETVCOMHDESEL); /* Set VCOMH deselect level */ - (void)SPI_SEND(spi, SSD1305_VCOMH_x7p7); /* Data 1: ~0.77 x Vcc */ - (void)SPI_SEND(spi, SSD1305_SETLUT); /* Set look up table for area color */ - (void)SPI_SEND(spi, 0x3f); /* Data 1: Pulse width: 31-63 */ - (void)SPI_SEND(spi, 0x3f); /* Data 2: Color A: 31-63 */ - (void)SPI_SEND(spi, 0x3f); /* Data 3: Color B: 31-63 */ - (void)SPI_SEND(spi, 0x3f); /* Data 4: Color C: 31-63 */ - (void)SPI_SEND(spi, SSD1305_DISPON); /* Display on, normal mode */ - (void)SPI_SEND(spi, SSD1305_DISPRAM); /* Resume to RAM content display */ - - /* Let go of the SPI lock and de-select the device */ - - ug_deselect(spi); - - /* Clear the framebuffer */ - - up_mdelay(100); - up_clear(priv); - return &priv->dev; -} |