summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2014-05-13 10:38:46 -0600
committerGregory Nutt <gnutt@nuttx.org>2014-05-13 10:38:46 -0600
commite744f86727763c51c67790d8f98aedcd57d1048a (patch)
treebca1f9d107a5ffe470468c24657c512d402abbdc
parent1a02c15166a34eb61a272f20d024af38e8e10bf7 (diff)
downloadnuttx-e744f86727763c51c67790d8f98aedcd57d1048a.tar.gz
nuttx-e744f86727763c51c67790d8f98aedcd57d1048a.tar.bz2
nuttx-e744f86727763c51c67790d8f98aedcd57d1048a.zip
SAM4E-EK: Add a driver for the on-board LCD (not tested on initial check-ing)
-rw-r--r--nuttx/ChangeLog2
-rw-r--r--nuttx/configs/sam4e-ek/Kconfig34
-rw-r--r--nuttx/configs/sam4e-ek/include/board.h17
-rw-r--r--nuttx/configs/sam4e-ek/src/Makefile4
-rw-r--r--nuttx/configs/sam4e-ek/src/sam_ili9325.c1418
-rw-r--r--nuttx/configs/sam4e-ek/src/sam_ili9523.c222
-rw-r--r--nuttx/drivers/mtd/ramtron.c6
-rw-r--r--nuttx/include/nuttx/lcd/ili9325.h10
8 files changed, 1472 insertions, 241 deletions
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog
index 3af6b8e61..7f6d2d4aa 100644
--- a/nuttx/ChangeLog
+++ b/nuttx/ChangeLog
@@ -7331,3 +7331,5 @@
(2014-5-12).
* drivers/mtd/ramtron.c: Add support for Fujitsu MB85RS1MT part. From
Charles Ash (2014-5-12).
+ * configs/sam4e-ek/src/sam_ili9325.c: Add an LCD driver for the SAM4E-EK
+ board. Untested on initial check-in (2014-5-13).
diff --git a/nuttx/configs/sam4e-ek/Kconfig b/nuttx/configs/sam4e-ek/Kconfig
index 470dbd8b8..e056070a7 100644
--- a/nuttx/configs/sam4e-ek/Kconfig
+++ b/nuttx/configs/sam4e-ek/Kconfig
@@ -62,17 +62,29 @@ config SAM4EEK_HSMCI_BLOCKDEVICE
endchoice # AT25 serial FLASH configuration
-config SAM4EEK_ILI9325
- bool "ILI9325-based LCD"
+if LCD
+
+choice
+ prompt "ILI9325-based LCD Color Configuration"
+ default SAM4EEK_LCD_RGB565
+
+config SAM4EEK_LCD_RGB565
+ bool "RGB565"
default n
- depends on EXPERIMENTAL
- select NX
- select NX_LCDDRIVER
- ---help---
- This option enables support for the SAM4E-EK on-board LCD. The
- SAM4E-EK carries a TFT transmissive LCD module with touch panel,
- FTM280C34D. Its integrated driver IC is ILI9325. The LCD display
- area is 2.8 inches diagonally measured, with a native resolution
- of 240 x 320 dots.
+config SAM4EEK_LCD_RGB24
+ bool "RGB24 / RGB888"
+ default n
+
+config SAM4EEK_LCD_RGB32
+ bool "RGB32"
+ default n
+
+endchoice # ILI9325-based LCD Color Configuration
+
+config SAM4EEK_LCD_BGCOLOR
+ hex "Initial background color"
+ default 0x00
+
+endif # LCD
endif # ARCH_BOARD_SAM4EEK
diff --git a/nuttx/configs/sam4e-ek/include/board.h b/nuttx/configs/sam4e-ek/include/board.h
index b31343378..cf16d045b 100644
--- a/nuttx/configs/sam4e-ek/include/board.h
+++ b/nuttx/configs/sam4e-ek/include/board.h
@@ -314,5 +314,22 @@ void sam_setled(int led, bool ledon);
void sam_setleds(uint8_t ledset);
#endif
+/************************************************************************************
+ * Name: stm32_lcdclear
+ *
+ * Description:
+ * This is a non-standard LCD interface just for the Shenzhou 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.
+ *
+ ************************************************************************************/
+
+#if defined(CONFIG_SAM4EEK_LCD_RGB565)
+void sam_lcdclear(uint16_t color);
+#else /* if defined(CONFIG_SAM4EEK_LCD_RGB24) defined(CONFIG_SAM4EEK_LCD_RGB32) */
+void sam_lcdclear(uint32_t color);
+#endif
+
#endif /* __ASSEMBLY__ */
#endif /* __ARCH_SAM4E_EK_INCLUDE_BOARD_H */
diff --git a/nuttx/configs/sam4e-ek/src/Makefile b/nuttx/configs/sam4e-ek/src/Makefile
index da5dda0cc..a04cb5d7c 100644
--- a/nuttx/configs/sam4e-ek/src/Makefile
+++ b/nuttx/configs/sam4e-ek/src/Makefile
@@ -58,6 +58,10 @@ ifeq ($(CONFIG_SAM34_HSMCI),y)
CSRCS += sam_hsmci.c
endif
+ifeq ($(CONFIG_LCD),y)
+CSRCS += sam_ili9325.c
+endif
+
ifeq ($(CONFIG_SAM34_SPI0),y)
CSRCS += sam_spi.c
ifeq ($(CONFIG_MTD_AT25),y)
diff --git a/nuttx/configs/sam4e-ek/src/sam_ili9325.c b/nuttx/configs/sam4e-ek/src/sam_ili9325.c
new file mode 100644
index 000000000..1cdd55b94
--- /dev/null
+++ b/nuttx/configs/sam4e-ek/src/sam_ili9325.c
@@ -0,0 +1,1418 @@
+/************************************************************************************
+ * configs/sam4e-ek/src/sam_ili9335.c
+ *
+ * Copyright (C) 2014 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * References:
+ * - This driver is a modification of the Shenzhou ILI9325 LCD driver.
+ * - ILI9325 Datasheet, Version: V0.43, ILI9325DS_V0.43.pdf, ILI TECHNOLOGY CORP.,
+ * - SAM4Ex Datasheet, Atmel
+ * - Atmel ILI9325 Sample code for the SAM4S
+ *
+ * Some the LCD and SMC initialization logic comes from Atmel sample code for the
+ * SAM4S. The Atmel sample code has a BSD-like license with an additional
+ * requirement that restricts the code from being used on anything but Atmel
+ * microprocessors. I do not believe that this file "derives" from the Atmel
+ * sample code nor do I believe that it contains anything but generally available
+ * ILI9325 and SAM4x logic. Credit, however, needs to go where it is due.
+ *
+ * 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.
+ *
+ ************************************************************************************/
+
+/**************************************************************************************
+ *
+ * The SAM4E-EK carries a TFT transmissive LCD module with touch panel, FTM280C34D.
+ * Its integrated driver IC is ILI9325. The LCD display area is 2.8 inches diagonally
+ * measured, with a native resolution of 240 x 320 dots.
+ *
+ * The SAM4E16 communicates with the LCD through PIOC where an 8-bit parallel "8080-
+ * like" protocol data bus has to be implemented in software.
+ *
+ * ---- ----- --------- --------------------------------
+ * PIN PIO SIGNAL NOTES
+ * ---- ----- --------- --------------------------------
+ * 1 VDD
+ * 2 PC7 DB17
+ * 3 PC6 DB16
+ * 4 PC5 DB15
+ * 5 PC4 DB14
+ * 6 PC3 DB13
+ * 7 PC2 DB12
+ * 8 PC1 DB11
+ * 9 PC0 DB10
+ * 10 DB9 Pulled low
+ * 11 DB8 Pulled low
+ * 12 DB7 Pulled low
+ * 13 DB6 Pulled low
+ * 14 DB5 Pulled low
+ * 15 DB4 Pulled low
+ * 16 DB3 Pulled low
+ * 17 DB2 Pulled low
+ * 18 DB1 Pulled low
+ * 19 DB0 Pulled low
+ * ---- ----- --------- --------------------------------
+ * 20 VDD
+ * 21 PC11 RD
+ * 22 PC8 WR
+ * 23 PC19 RS
+ * 24 PD18 CS Via J8, pulled high. Connects to NRST.
+ * 25 RESET Connects to NSRST
+ * 26 IM0 Pulled high
+ * 27 IM1 Grounded
+ * 28 GND
+ * ---- ----- --------- --------------------------------
+ * 29 [PC13] LED-A Backlight controls: PC13 enables
+ * 30 [PC13] LEDK1 AAT3155 charge pump that drives
+ * 31 [PC13] LEDK2 the backlight LEDs
+ * 32 [PC13] LEDK3
+ * 33 [PC13] LEDK4
+ * 34 [PC13] LEDK1
+ * ---- ----- --------- --------------------------------
+ * 35 Y+ These go to the ADS7843
+ * 36 Y- touchscreen controller.
+ * 37 X+
+ * 38 X-
+ * 39 NC
+ * ---- ----- --------- --------------------------------
+ *
+ * LCD backlight is made of 4 white chip LEDs in parallel, driven by an AAT3155
+ * charge pump, MN4. The AAT3155 is controlled by the SAM3U4E through a single line
+ * Simple Serial Control (S2Cwire) interface, which permits to enable, disable, and
+ * set the LED drive current (LED brightness control) from a 32-level logarithmic
+ * scale. Four resistors R93/R94/R95/R96 are implemented for optional current
+ * limitation.
+ *
+ **************************************************************************************/
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/lcd/lcd.h>
+#include <nuttx/lcd/ili9325.h>
+#include <nuttx/video/rgbcolors.h>
+
+#include <arch/irq.h>
+#include <arch/board/board.h>
+
+#include "up_arch.h"
+#include "sam_gpio.h"
+#include "sam_periphclks.h"
+#include "chip/sam_pmc.h"
+#include "chip/sam_smc.h"
+#include "sam4e-ek.h"
+
+#ifdef CONFIG_LCD
+
+/************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************/
+/* SMC must be selected */
+
+#if !defined(CONFIG_SAM34_SMC)
+# error "CONFIG_SAM34_SMC is required"
+#endif
+
+/* Check contrast selection */
+
+#if !defined(CONFIG_LCD_MAXCONTRAST)
+# define CONFIG_LCD_MAXCONTRAST 1
+#endif
+
+/* Check power setting */
+
+#if !defined(CONFIG_LCD_MAXPOWER)
+# define CONFIG_LCD_MAXPOWER 16
+#endif
+
+#if CONFIG_LCD_MAXPOWER < 16
+# error CONFIG_LCD_MAXPOWER should be >= 16
+# undef CONFIG_LCD_MAXPOWER
+# define CONFIG_LCD_MAXPOWER 16
+#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
+
+/* Background color */
+
+#if !defined(CONFIG_SAM4EEK_LCD_BGCOLOR)
+# define CONFIG_SAM4EEK_LCD_BGCOLOR 0
+#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
+# undef CONFIG_LCD_REGDEBUG
+#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 SAM_XRES 320
+# define SAM_YRES 240
+#else
+# define SAM_XRES 240
+# define SAM_YRES 320
+#endif
+
+/* Color depth and format */
+
+#if defined(CONFIG_SAM4EEK_LCD_RGB565)
+# define SAM_BPP 16
+# define SAM_COLORFMT FB_FMT_RGB16_565
+#elif defined(CONFIG_SAM4EEK_LCD_RGB24)
+# define SAM_BPP 24
+# define SAM_COLORFMT FB_FMT_RGB24
+#else /* if defined(CONFIG_SAM4EEK_LCD_RGB32) -- without ALPHA */
+# define SAM_BPP 32
+# define SAM_COLORFMT FB_FMT_RGB32
+#endif
+
+/* Color decoding macros */
+
+#ifdef CONFIG_SAM4EEK_LCD_RGB565
+# define RGB_RED(rgb) (((rgb) >> 8) & 0xf8)
+# define RGB_GREEN(rgb) (((rgb) >> 3) & 0xfc)
+# define RGB_BLUE(rgb) (((rgb) << 3) & 0xf8)
+#else /* RGB888 or RGB32 without ALPHA */
+# define RGB_RED(rgb) (((rgb) >> 16) & 0xff)
+# define RGB_GREEN(rgb) (((rgb) >> 8) & 0xff)
+# define RGB_BLUE(rgb) ( (rgb) & 0xff)
+#endif
+
+/* SAM4E-EK LCD Hardware Definitions **************************************************/
+/* LCD /CS is CE4, Bank 3 of NOR/SRAM Bank 1~4 */
+
+#define SAM_LCD_BASE ((uintptr_t)(0x60000000 | 0x01000000))
+#define LCD_INDEX (*(volatile uint8_t *)(SAM_LCD_BASE))
+#define LCD_DATA (*(volatile uint8_t *)(SAM_LCD_BASE + 2))
+
+/* LCD SMC hip select number to be set */
+
+#define SAM_LCD_CS 1
+
+/* Backlight */
+
+#define BKL_LEVELS 16
+#define BKL_PULSE_DURATION 24
+#define BKL_ENABLE_DURATION (128*1024)
+#define BKL_DISABLE_DURATION (128*1024)
+
+/* Debug ******************************************************************************/
+
+#ifdef CONFIG_DEBUG_LCD
+# define lcddbg dbg
+# define lcdvdbg vdbg
+#else
+# define lcddbg(x...)
+# define lcdvdbg(x...)
+#endif
+
+/************************************************************************************
+ * Private Type Definition
+ ************************************************************************************/
+
+/* Type definition for the correct size of one pixel (from the application standpoint). */
+
+#ifdef CONFIG_SAM4EEK_LCD_RGB565
+typedef uint16_t sam_color_t;
+#else /* RGB888 or RGB32 (without ALPHA) */
+typedef uint32_t sam_color_t;
+#endif
+
+/* This structure describes the LCD registers */
+
+struct lcd_regs_s
+{
+ volatile uint16_t index;
+ volatile uint16_t value;
+};
+
+/* This structure describes the state of this driver */
+
+struct sam_dev_s
+{
+ /* Publicly visible device structure */
+
+ struct lcd_dev_s dev;
+
+ /* Private LCD-specific information follows */
+
+ uint8_t power; /* Current power setting */
+ bool output; /* True: Configured for output */
+};
+
+/************************************************************************************
+ * Private Function Prototypes
+ ************************************************************************************/
+/* Low Level LCD access */
+
+static void sam_write_reg(uint8_t regaddr, uint16_t regval);
+static uint16_t sam_read_reg(uint8_t regaddr);
+static inline void sam_gram_prepare(void);
+static inline void sam_gram_write(sam_color_t color);
+static inline sam_color_t sam_gram_read(void);
+static void sam_set_cursor(uint16_t col, uint16_t row);
+
+/* Backlight/power controls */
+
+static void sam_disable_backlight(void);
+static void sam_set_backlight(unsigned int power);
+static int sam_poweroff(FAR struct sam_dev_s *priv);
+
+/* LCD Data Transfer Methods */
+
+static int sam_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer,
+ size_t npixels);
+static int sam_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer,
+ size_t npixels);
+
+/* LCD Configuration */
+
+static int sam_getvideoinfo(FAR struct lcd_dev_s *dev,
+ FAR struct fb_videoinfo_s *vinfo);
+static int sam_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 sam_getpower(struct lcd_dev_s *dev);
+static int sam_setpower(struct lcd_dev_s *dev, int power);
+static int sam_getcontrast(struct lcd_dev_s *dev);
+static int sam_setcontrast(struct lcd_dev_s *dev, unsigned int contrast);
+
+/* Initialization */
+
+static void sam_gpio_initialize(void);
+static inline void sam_smc_initialize(void);
+static void sam_lcd9325_initialize(void);
+static inline int sam_lcd_initialize(void);
+
+/************************************************************************************
+ * Private Data
+ ************************************************************************************/
+/* LCD GPIO configurations */
+
+static const uint32_t g_lcdpin[] =
+{
+ GPIO_SMC_D0, GPIO_SMC_D1, GPIO_SMC_D2, GPIO_SMC_D3, /* D0-D3 */
+ GPIO_SMC_D4, GPIO_SMC_D5, GPIO_SMC_D6, GPIO_SMC_D7, /* D4-D7 */
+ GPIO_SMC_NRD, GPIO_SMC_NWE, GPIO_SMC_A1, GPIO_SMC_NCS1_2, /* RD, WR, RS, CS */
+ GPIO_LCD_BKL /* Backlight control */
+};
+
+#define LCP_NPINS (sizeof(g_lcdpin) / sizeof(uint32_t))
+
+/* 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[SAM_XRES];
+
+/* This structure describes the overall LCD video controller */
+
+static const struct fb_videoinfo_s g_videoinfo =
+{
+ .fmt = SAM_COLORFMT, /* Color format: RGB16-565: RRRR RGGG GGGB BBBB */
+ .xres = SAM_XRES, /* Horizontal resolution in pixel columns */
+ .yres = SAM_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 = sam_putrun, /* Put a run into LCD memory */
+ .getrun = sam_getrun, /* Get a run from LCD memory */
+ .buffer = (uint8_t*)g_runbuffer, /* Run scratch buffer */
+ .bpp = SAM_BPP, /* Bits-per-pixel */
+};
+
+/* This is the standard, NuttX LCD driver object */
+
+static struct sam_dev_s g_lcddev =
+{
+ .dev =
+ {
+ /* LCD Configuration */
+
+ .getvideoinfo = sam_getvideoinfo,
+ .getplaneinfo = sam_getplaneinfo,
+
+ /* LCD RGB Mapping -- Not supported */
+ /* Cursor Controls -- Not supported */
+
+ /* LCD Specific Controls */
+
+ .getpower = sam_getpower,
+ .setpower = sam_setpower,
+ .getcontrast = sam_getcontrast,
+ .setcontrast = sam_setcontrast,
+ },
+};
+
+/************************************************************************************
+ * Private Functions
+ ************************************************************************************/
+
+/************************************************************************************
+ * Name: sam_write_reg
+ *
+ * Description:
+ * Write to an LCD register
+ *
+ ************************************************************************************/
+
+static void sam_write_reg(uint8_t regaddr, uint16_t regval)
+{
+ LCD_INDEX = 0;
+ LCD_INDEX = regaddr;
+
+ /* Write the 16-bit register value */
+
+ LCD_DATA = (uint8_t)(regval >> 8);
+ LCD_DATA = (uint8_t)(regval & 0xff);
+}
+
+/************************************************************************************
+ * Name: sam_read_reg
+ *
+ * Description:
+ * Read from an LCD register
+ *
+ ************************************************************************************/
+
+static uint16_t sam_read_reg(uint8_t regaddr)
+{
+ uint16_t regval;
+
+ LCD_INDEX = 0;
+ LCD_INDEX = regaddr;
+
+ /* Read and return the 16-bit register contents */
+
+ regval = (uint16_t)LCD_DATA;
+ regval = (regval << 8) | (uint16_t)LCD_DATA;
+
+ return regval;
+}
+
+/************************************************************************************
+ * Name: sam_gram_prepare
+ *
+ * Description:
+ * Setup to read or write multiple pixels to the GRAM memory
+ *
+ ************************************************************************************/
+
+static inline void sam_gram_prepare(void)
+{
+ LCD_INDEX = 0;
+ LCD_INDEX = ILI9325_GRAM_DATA_REG;
+}
+
+/************************************************************************************
+ * Name: sam_gram_write
+ *
+ * Description:
+ * Write one pixel to the GRAM memory
+ *
+ ************************************************************************************/
+
+static inline void sam_gram_write(sam_color_t color)
+{
+ LCD_DATA = RGB_RED(color);
+ LCD_DATA = RGB_GREEN(color);
+ LCD_DATA = RGB_BLUE(color);
+}
+
+/************************************************************************************
+ * Name: sam_gram_read
+ *
+ * Description:
+ * Read one 16-bit pixel to the GRAM memory
+ *
+ ************************************************************************************/
+
+static inline sam_color_t sam_gram_read(void)
+{
+ uint8_t value[2];
+
+ value[0] = LCD_DATA; /* Dummy read */
+ value[1] = LCD_DATA; /* Dummy read */
+ value[0] = LCD_DATA; /* RGB565 data upper byte */
+ value[1] = LCD_DATA; /* RGB565 data lower byte */
+
+ /* Convert and transfer the color to the user buffer */
+
+#if defined(CONFIG_SAM4EEK_LCD_RGB565)
+ /* Return the raw RGB565 color */
+
+ return (sam_color_t)value[0] << 8 | (sam_color_t)value[1];
+
+#else /* if defined(CONFIG_SAM4EEK_LCD_RGB24) || defined(CONFIG_SAM4EEK_LCD_RGB32) */
+ /* RRRR RGGG GGGB BBBB -> 0000 0000 RRRR R000 GGGG GG00 BBBB B000 */
+
+ return ((value[0] & 0xf8)) |
+ ((value[0] & 0x07) << 13) | ((value[1] & 0xE0) << 5) |
+ ((value[1] & 0x1f) << 19);
+#endif
+}
+
+/************************************************************************************
+ * Name: sam_set_cursor
+ *
+ * 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 sam_set_cursor(uint16_t col, uint16_t row)
+{
+ sam_write_reg(ILI9325_HORIZONTAL_GRAM_ADDR_SET, row);
+ sam_write_reg(ILI9325_VERTICAL_GRAM_ADDR_SET, col);
+}
+
+/************************************************************************************
+ * Name: sam_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 sam_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: sam_disable_backlight
+ *
+ * Description:
+ * Turn the backlight off.
+ *
+ ************************************************************************************/
+
+static void sam_disable_backlight(void)
+{
+ volatile int delay;
+
+ sam_gpiowrite(GPIO_LCD_BKL, false);
+ for (delay = 0; delay < BKL_DISABLE_DURATION; delay++);
+}
+
+/************************************************************************************
+ * Name: sam_set_backlight
+ *
+ * Description:
+ * The the backlight to the level associated with the specified power value.
+ *
+ ************************************************************************************/
+
+static void sam_set_backlight(unsigned int power)
+{
+ volatile int delay;
+ unsigned int level;
+ int i;
+
+ /* Scale the power setting to the range 1...BKL_LEVELS */
+
+ DEBUGASSERT(power > 0 && power <= CONFIG_LCD_MAXPOWER);
+ level = (power * BKL_LEVELS) / CONFIG_LCD_MAXPOWER;
+ if (level < 1)
+ {
+ level = 1;
+ }
+
+ level = BKL_LEVELS - level + 1;
+
+ /* Set the new backlight level */
+
+ for (i = 0; i < level; i++)
+ {
+ /* Generate a pulse to the charge pump */
+
+ sam_gpiowrite(GPIO_LCD_BKL, false);
+ for (delay = 0; delay < BKL_PULSE_DURATION; delay++);
+
+ sam_gpiowrite(GPIO_LCD_BKL, true);
+ for (delay = 0; delay < BKL_PULSE_DURATION; delay++);
+ }
+
+ /* Lock in this level */
+
+ for (delay = 0; delay < BKL_ENABLE_DURATION; delay++);
+}
+
+/************************************************************************************
+ * Name: sam_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 sam_poweroff(FAR struct sam_dev_s *priv)
+{
+ /* Turn the display off */
+
+ sam_write_reg(ILI9325_DISP_CTRL1, 0);
+
+ /* Disable the backlight */
+
+ sam_disable_backlight();
+
+ /* Remember the power off state */
+
+ priv->power = 0;
+ return OK;
+}
+
+/************************************************************************************
+ * Name: sam_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 sam_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer,
+ size_t npixels)
+{
+#if defined(CONFIG_SAM4EEK_LCD_RGB565)
+ FAR const uint16_t *src = (FAR const uint16_t*)buffer;
+#elif defined(CONFIG_SAM4EEK_LCD_RGB24)
+ FAR const uint8_t *src = (FAR const uint8_t*)buffer;
+#elif defined(CONFIG_SAM4EEK_LCD_RGB32)
+ FAR const uint32_t *src = (FAR const uint32_t*)buffer;
+#endif
+
+ /* 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);
+
+ /* Set the cursor position */
+
+ sam_set_cursor(col, row);
+
+ /* Prepare to write GRAM data */
+
+ sam_gram_prepare();
+
+ /* Then transfer the pixels as 3 8-bit transfers, each providing 6 bits of the
+ * color component in the MS bits.
+ */
+
+#if defined(CONFIG_SAM4EEK_LCD_RGB565) || defined(CONFIG_SAM4EEK_LCD_RGB32)
+ while (npixels--)
+ {
+ sam_color_t color = *src++;
+ LCD_DATA = RGB_RED(color);
+ LCD_DATA = RGB_GREEN(color);
+ LCD_DATA = RGB_BLUE(color);
+ }
+#else /* defined(CONFIG_SAM4EEK_LCD_RGB24) */
+ while (npixels--)
+ {
+ LCD_DATA = *src++;
+ LCD_DATA = *src++;
+ LCD_DATA = *src++;
+ }
+#endif
+
+ return OK;
+}
+
+/************************************************************************************
+ * Name: sam_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 sam_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer,
+ size_t npixels)
+{
+ uint8_t value[2];
+#if defined(CONFIG_SAM4EEK_LCD_RGB24)
+ FAR uint8_t *ptr = (FAR uint8_t *)buffer;
+#endif
+ /* Set the cursor position */
+
+ sam_set_cursor(col, row);
+
+ /* Prepare to write GRAM data */
+
+ sam_gram_prepare();
+
+ /* Then transfer the pixels, reading RGB565 and converting this to the format
+ * expected by the caller.
+ */
+
+ while (npixels--)
+ {
+ /* Read the RGB565 colot */
+
+ value[0] = LCD_DATA; /* Dummy read */
+ value[1] = LCD_DATA; /* Dummy read */
+ value[0] = LCD_DATA; /* Data upper byte */
+ value[1] = LCD_DATA; /* Data lower byte */
+
+ /* Convert and transfer the color to the user buffer */
+
+#if defined(CONFIG_SAM4EEK_LCD_RGB565)
+ /* Return the raw RGB565 color */
+
+ *buffer++ = (sam_color_t)value[0] << 8 | (sam_color_t)value[1];
+
+#elif defined(CONFIG_SAM4EEK_LCD_RGB24)
+ /* RRRR RGGG GGGB BBBB -> RRRR R000, GGGG GG00, BBBB B000 */
+
+ *ptr++ = (value[0] & 0xf8);
+ *ptr++ = (value[0] & 0x07) << 5) | ((value[1] & 0xe0) >> 3);
+ *ptr++ = (value[1] & 0x1f) << 3;
+
+#else /* if defined(CONFIG_SAM4EEK_LCD_RGB32) */
+ /* RRRR RGGG GGGB BBBB -> 0000 0000 RRRR R000 GGGG GG00 BBBB B000 */
+
+ *buffer++ = ((value[0] & 0xf8)) |
+ ((value[0] & 0x07) << 13) | ((value[1] & 0xE0) << 5) |
+ ((value[1] & 0x1f) << 19);
+#endif
+ }
+
+ return OK;
+}
+
+/************************************************************************************
+ * Name: sam_getvideoinfo
+ *
+ * Description:
+ * Get information about the LCD video controller configuration.
+ *
+ ************************************************************************************/
+
+static int sam_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: sam_getplaneinfo
+ *
+ * Description:
+ * Get information about the configuration of each LCD color plane.
+ *
+ ************************************************************************************/
+
+static int sam_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planeno,
+ FAR struct lcd_planeinfo_s *pinfo)
+{
+ DEBUGASSERT(dev && 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: sam_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 sam_getpower(struct lcd_dev_s *dev)
+{
+ FAR struct sam_dev_s *priv = (FAR struct sam_dev_s *)dev;
+
+ lcdvdbg("power: %d\n", 0);
+ return priv->power;
+}
+
+/************************************************************************************
+ * Name: sam_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 sam_setpower(struct lcd_dev_s *dev, int power)
+{
+ FAR struct sam_dev_s *priv = (FAR struct sam_dev_s *)dev;
+
+ lcdvdbg("power: %d\n", power);
+ DEBUGASSERT((unsigned)power <= CONFIG_LCD_MAXPOWER);
+
+ /* Set new power level */
+
+ if (power > 0)
+ {
+ /* Then turn the display on */
+
+ sam_write_reg(ILI9325_DISP_CTRL1,
+ ILI9325_DISP_CTRL1_BASEE | ILI9325_DISP_CTRL1_GON |
+ ILI9325_DISP_CTRL1_DTE | ILI9325_DISP_CTRL1_D(3));
+
+ /* Set the backlight level */
+
+ sam_set_backlight((unsigned int)power);
+ up_mdelay(50);
+ priv->power = power;
+ }
+ else
+ {
+ /* Turn the display off */
+
+ sam_poweroff(priv);
+ }
+
+ return OK;
+}
+
+/************************************************************************************
+ * Name: sam_getcontrast
+ *
+ * Description:
+ * Get the current contrast setting (0-CONFIG_LCD_MAXCONTRAST).
+ *
+ ************************************************************************************/
+
+static int sam_getcontrast(struct lcd_dev_s *dev)
+{
+ lcdvdbg("Not implemented\n");
+ return -ENOSYS;
+}
+
+/************************************************************************************
+ * Name: sam_setcontrast
+ *
+ * Description:
+ * Set LCD panel contrast (0-CONFIG_LCD_MAXCONTRAST).
+ *
+ ************************************************************************************/
+
+static int sam_setcontrast(struct lcd_dev_s *dev, unsigned int contrast)
+{
+ lcdvdbg("contrast: %d\n", contrast);
+ return -ENOSYS;
+}
+
+/************************************************************************************
+ * Name: sam_gpio_initialize
+ *
+ * Description:
+ * Configure LCD GPIO pins
+ *
+ ************************************************************************************/
+
+static inline void sam_gpio_initialize(void)
+{
+ int i;
+
+ /* Configure all LCD pins pins (backlight is initially off) */
+
+ for (i = 0; i < LCP_NPINS; i++)
+ {
+ sam_configgpio(g_lcdpin[i]);
+ }
+}
+
+/************************************************************************************
+ * Name: sam_smc_initialize
+ *
+ * Description:
+ * Configure LCD SMC interface
+ *
+ ************************************************************************************/
+
+static inline void sam_smc_initialize(void)
+{
+ uintptr_t smcbase = SAM_SMCCS_BASE(SAM_LCD_CS);
+ uint32_t regval;
+
+ /* Configure SMC interface for the LCD */
+
+ regval = SMCCS_SETUP_NWESETUP(2) | SMCCS_SETUP_NCSWRSETUP(2) |
+ SMCCS_SETUP_NRDSETUP(2) | SMCCS_SETUP_NCSRDSETUP(2);
+ putreg32(regval, smcbase + SAM_SMCCS_SETUP_OFFSET);
+
+ regval = SMCCS_PULSE_NWEPULSE(4) | SMCCS_PULSE_NCSWRPULSE(4) |
+ SMCCS_PULSE_NRDPULSE(10) | SMCCS_PULSE_NCSRDPULSE(10);
+ putreg32(regval, smcbase + SAM_SMCCS_PULSE_OFFSET);
+
+ regval = SMCCS_CYCLE_NWECYCLE(10) | SMCCS_CYCLE_NRDCYCLE(22);
+ putreg32(regval, smcbase + SAM_SMCCS_CYCLE_OFFSET);
+
+#ifdef SMCCS_MODE_DBW_8BITS /* SAM3U, SAM3X, SAM3A */
+ regval = SMCCS_MODE_READMODE | SMCCS_MODE_WRITEMODE | SMCCS_MODE_DBW_8BITS;
+#else
+ regval = SMCCS_MODE_READMODE | SMCCS_MODE_WRITEMODE;
+#endif
+ putreg32(regval, smcbase + SAM_SMCCS_MODE_OFFSET);
+}
+
+/************************************************************************************
+ * Name: sam_lcd9325_initialize
+ *
+ * Description:
+ * Initialize the ILI9325 LCD.
+ *
+ ************************************************************************************/
+
+static void sam_lcd9325_initialize(void)
+{
+ uint16_t regval;
+
+ /* Turn off the LCD ***************************************************************/
+
+ sam_write_reg(ILI9325_DISP_CTRL1,
+ ILI9325_DISP_CTRL1_GON | ILI9325_DISP_CTRL1_DTE |
+ ILI9325_DISP_CTRL1_D(3));
+
+ /* Initial sequence ***************************************************************/
+ /* Disable sleep and standby mode*/
+
+ sam_write_reg(ILI9325_POWER_CTRL1, 0);
+
+ /* Start internal OSC */
+
+ sam_write_reg(ILI9325_START_OSC_CTRL, ILI9325_START_OSC_CTRL_EN);
+
+ /* Set SS bit and direction output from S720 to S1 */
+
+ sam_write_reg(ILI9325_DRIVER_OUTPUT_CTRL1, ILI9325_DRIVER_OUTPUT_CTRL1_SS);
+
+ /* Set 1 line inversion */
+
+ sam_write_reg(ILI9325_LCD_DRIVING_CTRL,
+ ILI9325_LCD_DRIVING_CTRL_BIT10 | ILI9325_LCD_DRIVING_CTRL_EOR |
+ ILI9325_LCD_DRIVING_CTRL_BC0);
+
+ /* Disable resizing feature */
+
+ sam_write_reg(ILI9325_RESIZE_CTRL, 0);
+
+ /* Set the back porch and front porch */
+
+ sam_write_reg(ILI9325_DISP_CTRL2,
+ ILI9325_DISP_CTRL2_BP(7) | ILI9325_DISP_CTRL2_FP(2));
+
+ /* Set non-display area refresh cycle ISC[3:0] */
+
+ sam_write_reg(ILI9325_DISP_CTRL3, 0);
+
+ /* Disable FMARK function */
+
+ sam_write_reg(ILI9325_DISP_CTRL4, 0);
+
+ /* 18-bit RGB interface and writing display data by the system interface */
+
+ sam_write_reg(ILI9325_RGB_DISP_INTERFACE_CTRL1, 0);
+
+ /* Set the output position of frame cycle */
+
+ sam_write_reg(ILI9325_FRAME_MAKER_SHIFT, 0);
+
+ /* RGB interface polarity */
+
+ sam_write_reg(ILI9325_RGB_DISP_INTERFACE_CTRL2, 0);
+
+ /* Power on sequence **************************************************************/
+ /* Disable sleep and standby mode */
+
+ sam_write_reg(ILI9325_POWER_CTRL1, 0);
+
+ /* Select the operating frequency of the step-up circuit 1,2 and set the
+ * ratio factor of Vci
+ */
+
+ sam_write_reg(ILI9325_POWER_CTRL2, 0);
+
+ /* Set VREG1OUT voltage */
+
+ sam_write_reg(ILI9325_POWER_CTRL3, 0);
+
+ /* Set VCOM amplitude */
+
+ sam_write_reg(ILI9325_POWER_CTRL4, 0);
+ up_mdelay(200);
+
+ /* Enable power supply and source driver ******************************************/
+ /* Adjust the constant current and set the factor used in the step-up
+ * circuits.
+ */
+
+ sam_write_reg(ILI9325_POWER_CTRL1,
+ ILI9325_POWER_CTRL1_SAP | ILI9325_POWER_CTRL1_BT(2) |
+ ILI9325_POWER_CTRL1_APE | ILI9325_POWER_CTRL1_AP(1));
+
+ /* Select the operating frequency of the step-up circuit 1,2 and set the
+ * ratio factor of Vci
+ */
+
+ sam_write_reg(ILI9325_POWER_CTRL2,
+ ILI9325_POWER_CTRL2_DC1(2) | ILI9325_POWER_CTRL2_DC0(2) |
+ ILI9325_POWER_CTRL2_VC(7));
+ up_mdelay(50);
+
+ /* Internal reference voltage= Vci */
+
+ sam_write_reg(ILI9325_POWER_CTRL3,
+ ILI9325_POWER_CTRL3_PON | ILI9325_POWER_CTRL3_VRH(11));
+ up_mdelay(50);
+
+ /* Set VDV[4:0] for VCOM amplitude */
+
+ sam_write_reg(ILI9325_POWER_CTRL4, ILI9325_POWER_CTRL4_VDV(17));
+
+ /* Set VCM[5:0] for VCOMH */
+
+ sam_write_reg(ILI9325_POWER_CTRL7, ILI9325_POWER_CTRL7_VCM(25));
+
+ /* Set Frame Rate */
+
+ sam_write_reg(ILI9325_FRAME_RATE_AND_COLOR_CTRL,
+ ILI9325_FRAME_RATE_AND_COLOR_CTRL_FRS(13));
+ up_mdelay(50);
+
+ /* Adjust the Gamma Curve */
+
+ sam_write_reg(ILI9325_GAMMA_CTRL1, 9);
+ sam_write_reg(ILI9325_GAMMA_CTRL2,
+ ILI9325_GAMMA_CTRL2_KP3(2) | ILI9325_GAMMA_CTRL2_KP2(4));
+ sam_write_reg(ILI9325_GAMMA_CTRL3,
+ ILI9325_GAMMA_CTRL3_KP5(2) | ILI9325_GAMMA_CTRL3_KP4(0));
+ sam_write_reg(ILI9325_GAMMA_CTRL4,
+ ILI9325_GAMMA_CTRL4_RP1(0) | ILI9325_GAMMA_CTRL4_RP0(7));
+ sam_write_reg(ILI9325_GAMMA_CTRL5,
+ ILI9325_GAMMA_CTRL5_VRP1(20) | ILI9325_GAMMA_CTRL5_VRP0(4));
+ sam_write_reg(ILI9325_GAMMA_CTRL6,
+ ILI9325_GAMMA_CTRL6_KN1(7) | ILI9325_GAMMA_CTRL6_KN0(5));
+ sam_write_reg(ILI9325_GAMMA_CTRL7,
+ ILI9325_GAMMA_CTRL7_KN3(3) | ILI9325_GAMMA_CTRL7_KN2(5));
+ sam_write_reg(ILI9325_GAMMA_CTRL8,
+ ILI9325_GAMMA_CTRL8_KN5(7) | ILI9325_GAMMA_CTRL8_KN4(7));
+ sam_write_reg(ILI9325_GAMMA_CTRL9,
+ ILI9325_GAMMA_CTRL9_RN1(7) | ILI9325_GAMMA_CTRL9_RN0(1));
+ sam_write_reg(ILI9325_GAMMA_CTRL10,
+ ILI9325_GAMMA_CTRL10_VRN1(0) | ILI9325_GAMMA_CTRL10_VRN0(14));
+
+ /* Set the Entry Mode:
+ *
+ * AM controls the GRAM update direction.
+ * 0 = The address is updated in horizontal writing direction.
+ * 1 = The address is updated in vertical writing direction.
+ *
+ * I/D[1:0] controls the address counter (AC) to automatically increase or
+ * decrease by 1 when update one pixel display data.
+ *
+ * 00 = Horizontal decrement, Vertical decrement
+ * 01 = Horizontal increment, Vertical decrement
+ * 10 = Horizontal decrement, Vertical increment
+ * 11 = Horizontal increment, Vertical increment
+ *
+ * ORG moves the origin address according to the ID setting when a window address
+ * area is made.
+ * 0 = The origin address is not moved.
+ * 1 = The original address moves according to the I/D[1:0] setting.
+ *
+ * BGR swaps the R and B order of written data.
+ * 0 = Follow the RGB order to write the pixel data.
+ * 1 = Swap the RGB data to BGR in writing into GRAM.
+ *
+ * TRI = 1: Data are transferred to the internal RAM in 8-bit x 3 transfers mode
+ * via the 8-bit interface.
+ *
+ * DFM + TRI: Data is transferred as 3 byte transfers
+ *
+ * Use the high speed write mode (HWM=1). When TRI = 1, data are transferred to
+ * the internal RAM in 8-bit x 3 transfers mode via the 8-bit interface. DFM set
+ * the mode of transferring data to the internal RAM when TRI = 1.
+ * I/D[1:0] = 11 Horizontal : increment Vertical : increment, AM=0:Horizontal
+ */
+
+#if defined(CONFIG_LCD_LANDSCAPE)
+ /* Landscape: Horizontal increment/ Vertical decrement, address is update in
+ * horizontal direction
+ */
+
+ regval = ILI9325_ENTRY_MODE_ID(1) | ILI9325_ENTRY_MODE_ORG | ILI9325_ENTRY_MODE_HWM |
+ ILI9325_ENTRY_MODE_BGR | ILI9325_ENTRY_MODE_TRI | ILI9325_ENTRY_MODE_DFM;
+
+#elif defined(CONFIG_LCD_RLANDSCAPE)
+ /* Landscape: Horizontal decrement/ Vertical increment, address is update in
+ * horizontal direction
+ */
+
+ regval = ILI9325_ENTRY_MODE_ID(2) | ILI9325_ENTRY_MODE_ORG | ILI9325_ENTRY_MODE_HWM |
+ ILI9325_ENTRY_MODE_BGR | ILI9325_ENTRY_MODE_TRI | ILI9325_ENTRY_MODE_DFM;
+
+#elif defined(CONFIG_LCD_PORTRAIT)
+ /* Landscape: Horizontal decrement/ Vertical decrement, address is update in
+ * vertical direction
+ */
+
+ regval = ILI9325_ENTRY_MODE_AM | ILI9325_ENTRY_MODE_ID(0) | ILI9325_ENTRY_MODE_ORG |
+ ILI9325_ENTRY_MODE_HWM | ILI9325_ENTRY_MODE_BGR | ILI9325_ENTRY_MODE_TRI |
+ ILI9325_ENTRY_MODE_DFM;
+
+#else /* if defined(CONFIG_LCD_RPORTRAIT) */
+ /* Landscape: Horizontal increment/ Vertical increment, address is update in
+ * vertical direction
+ */
+
+ regval = ILI9325_ENTRY_MODE_AM | ILI9325_ENTRY_MODE_ID(3) | ILI9325_ENTRY_MODE_ORG |
+ ILI9325_ENTRY_MODE_HWM | ILI9325_ENTRY_MODE_BGR | ILI9325_ENTRY_MODE_TRI |
+ ILI9325_ENTRY_MODE_DFM;
+#endif
+
+ sam_write_reg(ILI9325_ENTRY_MODE, regval);
+
+ /* Driver Output Control
+ *
+ * SS: Select the shift direction of outputs from the source driver
+ * 0 = The shift direction of outputs is from S1 to S720
+ * 1 = The shift direction of outputs is from S720 to S1
+ * SM: Sets the gate driver pin arrangement in combination with the GS bit
+ */
+
+#if defined(CONFIG_LCD_LANDSCAPE) || defined(CONFIG_LCD_RPORTRAIT)
+ /* Horizontal increment */
+
+ regval = 0;
+
+#else /* defined(CONFIG_LCD_RLANDSCAPE) || defined(CONFIG_LCD_PORTRAIT) */
+ /* Horizontal decrement */
+
+ regval = ILI9325_DRIVER_OUTPUT_CTRL1_SS;
+#endif
+
+ sam_write_reg(ILI9325_DRIVER_OUTPUT_CTRL1, regval);
+
+ /* Set the number of lines to drive the LCD at an interval of 8 lines. The scan
+ * direction is from G320 to G1
+ */
+
+ regval = ILI9325_DRIVER_OUTPUT_CTRL2_NL((SAM_XRES / 8) - 1);
+
+#if defined(CONFIG_LCD_LANDSCAPE) || defined(CONFIG_LCD_PORTRAIT)
+ /* Vertical decrement */
+
+ regval |= ILI9325_DRIVER_OUTPUT_CTRL2_GS;
+#endif
+
+ sam_write_reg(ILI9325_DRIVER_OUTPUT_CTRL2, regval);
+
+ /* Vertical Scrolling *************************************************************/
+ /* Disable scrolling and enable the grayscale inversion */
+
+ sam_write_reg(ILI9325_BASE_IMG_DISP_CTRL, ILI9325_BASE_IMG_DISP_CTRL_REV);
+ sam_write_reg(ILI9325_VERTICAL_SCROLL_CTRL, 0);
+
+ /* Disable Partial Display */
+
+ sam_write_reg(ILI9325_PARTIAL_IMG1_DISP_SHIFT, 0);
+ sam_write_reg(ILI9325_PARTIAL_IMG1_AREA_START_LINE, 0);
+ sam_write_reg(ILI9325_PARTIAL_IMG1_AREA_END_LINE, 0);
+ sam_write_reg(ILI9325_PARTIAL_IMG2_DISP_SHIFT, 0);
+ sam_write_reg(ILI9325_PARTIAL_IMG2_AREA_START_LINE, 0);
+ sam_write_reg(ILI9325_PARTIAL_IMG2_AREA_END_LINE, 0);
+
+ /* Panel Control */
+
+ sam_write_reg(ILI9325_PANEL_INTERFACE_CTRL1,
+ ILI9325_PANEL_INTERFACE_CTRL1_RTNI(16));
+ sam_write_reg(ILI9325_PANEL_INTERFACE_CTRL2,
+ ILI9325_PANEL_INTERFACE_CTRL2_NOWI(6));
+ sam_write_reg(ILI9325_PANEL_INTERFACE_CTRL4,
+ ILI9325_PANEL_INTERFACE_CTRL4_DIVE(1) |
+ ILI9325_PANEL_INTERFACE_CTRL4_RTNE(16));
+
+ /* Set the drawing window */
+
+ sam_write_reg(ILI9325_HORIZONTAL_ADDR_START, 0);
+ sam_write_reg(ILI9325_HORIZONTAL_ADDR_END, SAM_XRES - 1);
+ sam_write_reg(ILI9325_VERTICAL_ADDR_START, 0);
+ sam_write_reg(ILI9325_VERTICAL_ADDR_END, SAM_YRES - 1);
+
+ /* Home the cursor */
+
+ sam_set_cursor(0, 0);
+}
+
+/************************************************************************************
+ * Name: sam_lcd_initialize
+ *
+ * Description:
+ * Initialize the LCD panel
+ *
+ ************************************************************************************/
+
+static inline int sam_lcd_initialize(void)
+{
+ uint16_t id;
+
+ /* Check LCD ID */
+
+ id = sam_read_reg(ILI9325_DEVICE_CODE_REG);
+ lcdvdbg("LCD ID: %04x\n", id);
+
+ /* Initialize the LCD hardware */
+
+ if (id != ILI9325_DEVICE_CODE)
+ {
+ lcddbg("ERROR: Unsupported LCD type: %04x\n", id);
+ return -ENODEV;
+ }
+
+ sam_lcd9325_initialize();
+ return OK;
+}
+
+/************************************************************************************
+ * Public Functions
+ ************************************************************************************/
+
+/************************************************************************************
+ * Name: up_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).
+ *
+ ************************************************************************************/
+
+int up_lcdinitialize(void)
+{
+ FAR struct sam_dev_s *priv = &g_lcddev;
+ int ret;
+
+ lcdvdbg("Initializing\n");
+
+ /* Configure all LCD pins pins (backlight is initially off) */
+
+ sam_gpio_initialize();
+
+ /* Enable peripheral clock */
+
+ sam_smc_enableclk();
+
+ /* Configure SMC interface for the LCD */
+
+ sam_smc_initialize();
+
+ /* Identify and configure the LCD */
+
+ up_mdelay(50);
+ ret = sam_lcd_initialize();
+ if (ret == OK)
+ {
+ /* Clear the display (setting it to the color 0=black) */
+
+ sam_lcdclear(CONFIG_SAM4EEK_LCD_BGCOLOR);
+
+ /* Turn the display off */
+
+ sam_poweroff(priv);
+ }
+
+ return ret;
+}
+
+/************************************************************************************
+ * Name: up_lcdgetdev
+ *
+ * Description:
+ * Return a a reference to the LCD object for the specified LCD. This allows
+ * support for multiple LCD devices.
+ *
+ ************************************************************************************/
+
+FAR struct lcd_dev_s *up_lcdgetdev(int lcddev)
+{
+ DEBUGASSERT(lcddev == 0);
+ return &g_lcddev.dev;
+}
+
+/************************************************************************************
+ * Name: up_lcduninitialize
+ *
+ * Description:
+ * Uninitialize the LCD support
+ *
+ ************************************************************************************/
+
+void up_lcduninitialize(void)
+{
+ FAR struct sam_dev_s *priv = &g_lcddev;
+
+ /* Put the LCD in the lowest possible power state */
+
+ sam_poweroff(priv);
+}
+
+/************************************************************************************
+ * Name: sam_lcdclear
+ *
+ * Description:
+ * This is a non-standard LCD interface just for the SAM4E-EK 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.
+ *
+ ************************************************************************************/
+
+#if defined(CONFIG_SAM4EEK_LCD_RGB565)
+void sam_lcdclear(uint16_t color)
+#else /* if defined(CONFIG_SAM4EEK_LCD_RGB24) defined(CONFIG_SAM4EEK_LCD_RGB32) */
+void sam_lcdclear(uint32_t color)
+#endif
+{
+ uint8_t r = RGB_RED(color);
+ uint8_t g = RGB_GREEN(color);
+ uint8_t b = RGB_BLUE(color);
+ uint32_t i;
+
+ sam_set_cursor(0, 0);
+ sam_gram_prepare();
+
+ for (i = SAM_XRES * SAM_YRES; i > 0; i--)
+ {
+ LCD_DATA = r;
+ LCD_DATA = g;
+ LCD_DATA = b;
+ }
+}
+
+#endif /* CONFIG_LCD */
diff --git a/nuttx/configs/sam4e-ek/src/sam_ili9523.c b/nuttx/configs/sam4e-ek/src/sam_ili9523.c
deleted file mode 100644
index ccd9e5c7c..000000000
--- a/nuttx/configs/sam4e-ek/src/sam_ili9523.c
+++ /dev/null
@@ -1,222 +0,0 @@
-/**************************************************************************************
- * configs/sam4e-ek/src/sam_ili9325.c
- *
- * Copyright (C) 2014 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.
- *
- **************************************************************************************/
-
-/**************************************************************************************
- *
- * The SAM4E-EK carries a TFT transmissive LCD module with touch panel, FTM280C34D.
- * Its integrated driver IC is ILI9325. The LCD display area is 2.8 inches diagonally
- * measured, with a native resolution of 240 x 320 dots.
- *
- * The SAM4E16 communicates with the LCD through PIOC where an 8-bit parallel "8080-
- * like" protocol data bus has to be implemented in software.
- *
- * ---- ----- --------- --------------------------------
- * PIN PIO SIGNAL NOTES
- * ---- ----- --------- --------------------------------
- * 1 VDD
- * 2 PC7 DB17
- * 3 PC6 DB16
- * 4 PC5 DB15
- * 5 PC4 DB14
- * 6 PC3 DB13
- * 7 PC2 DB12
- * 8 PC1 DB11
- * 9 PC0 DB10
- * 10 DB9 Pulled low
- * 11 DB8 Pulled low
- * 12 DB7 Pulled low
- * 13 DB6 Pulled low
- * 14 DB5 Pulled low
- * 15 DB4 Pulled low
- * 16 DB3 Pulled low
- * 17 DB2 Pulled low
- * 18 DB1 Pulled low
- * 19 DB0 Pulled low
- * ---- ----- --------- --------------------------------
- * 20 VDD
- * 21 PC11 RD
- * 22 PC8 WR
- * 23 PC19 RS
- * 24 PD18 CS Via J8, pulled high. Connects to NRST.
- * 25 RESET Connects to NSRST
- * 26 IM0 Pulled high
- * 27 IM1 Grounded
- * 28 GND
- * ---- ----- --------- --------------------------------
- * 29 [PC13] LED-A Backlight controls: PC13 enables
- * 30 [PC13] LEDK1 AAT3155 charge pump that drives
- * 31 [PC13] LEDK2 the backlight LEDs
- * 32 [PC13] LEDK3
- * 33 [PC13] LEDK4
- * 34 [PC13] LEDK1
- * ---- ----- --------- --------------------------------
- * 35 Y+ These go to the ADS7843
- * 36 Y- touchscreen controller.
- * 37 X+
- * 38 X-
- * 39 NC
- * ---- ----- --------- --------------------------------
- *
- * LCD backlight is made of 4 white chip LEDs in parallel, driven by an AAT3155
- * charge pump, MN4. The AAT3155 is controlled by the SAM3U4E through a single line
- * Simple Serial Control (S2Cwire) interface, which permits to enable, disable, and
- * set the LED drive current (LED brightness control) from a 32-level logarithmic
- * scale. Four resistors R93/R94/R95/R96 are implemented for optional current
- * limitation.
- *
- **************************************************************************************/
-
-/**************************************************************************************
- * Included Files
- **************************************************************************************/
-
-/**************************************************************************************
- * Pre-processor Definitions
- **************************************************************************************/
-
-/* Configuration **********************************************************************/
-
-/* Define the following to enable register-level debug output */
-
-#undef CONFIG_LCD_REGDEBUG
-
-/* Verbose debug must also be enabled */
-
-#ifndef CONFIG_DEBUG
-# undef CONFIG_DEBUG_VERBOSE
-# undef CONFIG_DEBUG_LED
-#endif
-
-#ifndef CONFIG_DEBUG_VERBOSE
-# undef CONFIG_LCD_REGDEBUG
-#endif
-
-/* Debug ******************************************************************************/
-
-#ifdef CONFIG_LCD_REGDEBUG
-# define regdbg(format, arg...) vdbg(format, ##arg)
-#else
-# define regdbg(x...)
-#endif
-
-#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
- **************************************************************************************/
-
-/**************************************************************************************
- * Private Function Prototypes
- **************************************************************************************/
-
-/**************************************************************************************
- * Private Data
- **************************************************************************************/
-
-/**************************************************************************************
- * Private Functions
- **************************************************************************************/
-
-/**************************************************************************************
- * Public Functions
- **************************************************************************************/
-
-/**************************************************************************************
- * Name: up_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).
- *
- **************************************************************************************/
-
-int up_lcdinitialize(void)
-{
- /* Not implemented
- *
- * If you want to implement LCD support, here are some references:
- *
- * 1. Atmel Sample Code (ASF). There is no example for the SAM4E-EK, but there is for
- * the SAM4S-EK. The LCD and its processor connectivity appear to be equivalent
- * to the SAM4E-EK so this sample code should be a good place to begin. NOTE that
- * the clock frequencies may be different and pin usage may be different. So it
- * may be necessary to adjust the SAM configuration to use this example.
- * 2. There is an example of an LCD driver for the SAM3U at configs/sam4u-ek/src/up_lcd.c.
- * That LCD driver is for an LCD with a different LCD controller but should provide
- * the NuttX SAM framework for an LCD driver.
- * 3. There are other LCD drivers for different MCUs that do support the ILI9325
- * LCD. Look at configs/shenzhou/src/up_ili93xx.c, configs/stm3220g-eval/src/up_lcd.c,
- * and configs/stm3240g-eval/src/up_lcd.c. I believe that the Shenzhou driver is
- * the most recent.
- */
-
- return -ENOSYS;
-}
-
-/**************************************************************************************
- * Name: up_lcdgetdev
- *
- * Description:
- * Return a a reference to the LCD object for the specified LCD. This allows
- * support for multiple LCD devices.
- *
- **************************************************************************************/
-
-FAR struct lcd_dev_s *up_lcdgetdev(int lcddev)
-{
- /* Not implemented */
-
- return NULL;
-}
-
-/**************************************************************************************
- * Name: up_lcduninitialize
- *
- * Description:
- * Unitialize the framebuffer support.
- *
- **************************************************************************************/
-
-void up_lcduninitialize(void)
-{
- /* Not implemented */
-}
diff --git a/nuttx/drivers/mtd/ramtron.c b/nuttx/drivers/mtd/ramtron.c
index 403867cd2..8bf2192f5 100644
--- a/nuttx/drivers/mtd/ramtron.c
+++ b/nuttx/drivers/mtd/ramtron.c
@@ -355,9 +355,9 @@ static inline int ramtron_readid(struct ramtron_dev_s *priv)
}
}
- memory = SPI_SEND(priv->dev, RAMTRON_DUMMY);
- capacity = SPI_SEND(priv->dev, RAMTRON_DUMMY); /* fram.id1 */
- part = SPI_SEND(priv->dev, RAMTRON_DUMMY); /* fram.id2 */
+ memory = SPI_SEND(priv->dev, RAMTRON_DUMMY);
+ capacity = SPI_SEND(priv->dev, RAMTRON_DUMMY); /* fram.id1 */
+ part = SPI_SEND(priv->dev, RAMTRON_DUMMY); /* fram.id2 */
/* Deselect the FLASH and unlock the bus */
diff --git a/nuttx/include/nuttx/lcd/ili9325.h b/nuttx/include/nuttx/lcd/ili9325.h
index dc6750337..94bea4c2a 100644
--- a/nuttx/include/nuttx/lcd/ili9325.h
+++ b/nuttx/include/nuttx/lcd/ili9325.h
@@ -147,7 +147,7 @@
#define ILI9325_DISP_CTRL1_D_SHIFT 0
#define ILI9325_DISP_CTRL1_D_MASK (3 << ILI9325_DISP_CTRL1_D_SHIFT)
-# define ILI9325_DISP_CTRL1_D(n) ((uint16_t)(n) << ILI9325_DISP_CTRL1_D_SHIFT)))
+# define ILI9325_DISP_CTRL1_D(n) ((uint16_t)(n) << ILI9325_DISP_CTRL1_D_SHIFT)
#define ILI9325_DISP_CTRL1_CL (1 << 3)
#define ILI9325_DISP_CTRL1_DTE (1 << 4)
#define ILI9325_DISP_CTRL1_GON (1 << 5)
@@ -160,7 +160,7 @@
#define ILI9325_DISP_CTRL2_BP_SHIFT 0
#define ILI9325_DISP_CTRL2_BP_MASK (0xf << ILI9325_DISP_CTRL2_BP_SHIFT)
-# define ILI9325_DISP_CTRL2_BP(n) ((uint16_t)(n) << ILI9325_DISP_CTRL2_BP_SHIFT)))
+# define ILI9325_DISP_CTRL2_BP(n) ((uint16_t)(n) << ILI9325_DISP_CTRL2_BP_SHIFT)
#define ILI9325_DISP_CTRL2_FP_SHIFT 8
#define ILI9325_DISP_CTRL2_FP_MASK (0xf << ILI9325_DISP_CTRL2_FP_SHIFT)
# define ILI9325_DISP_CTRL2_FP(n) ((uint16_t)(n) << ILI9325_DISP_CTRL2_FP_SHIFT)
@@ -203,7 +203,7 @@
#define ILI9325_FRAME_MAKER_SHIFT_FMP_SHIFT 0
#define ILI9325_FRAME_MAKER_SHIFT_FMP_MASK (0x1ff << ILI9325_FRAME_MAKER_SHIFT_FMP_SHIFT)
-# define ILI9325_FRAME_MAKER_SHIFT_FMP(n) ((uint16_t)(n) << ILI9325_FRAME_MAKER_SHIFT_FMP_SHIFT)))
+# define ILI9325_FRAME_MAKER_SHIFT_FMP(n) ((uint16_t)(n) << ILI9325_FRAME_MAKER_SHIFT_FMP_SHIFT)
/* ILI9325_RGB_DISP_INTERFACE_CTRL2, RGB Display Interface Control 2, Offset: 0x0f */
@@ -217,11 +217,11 @@
#define ILI9325_POWER_CTRL1_STB (1 << 0)
#define ILI9325_POWER_CTRL1_SLP (1 << 1)
#define ILI9325_POWER_CTRL1_DSTB (1 << 2)
-#define ILI9325_POWER_CTRL1_AP_SHIFT 4
+#define ILI9325_POWER_CTRL1_AP_SHIFT 4
#define ILI9325_POWER_CTRL1_AP_MASK (7 << ILI9325_POWER_CTRL1_AP_SHIFT)
# define ILI9325_POWER_CTRL1_AP(n) ((uint16_t)(n) << ILI9325_POWER_CTRL1_AP_SHIFT)
#define ILI9325_POWER_CTRL1_APE (1 << 7)
-#define ILI9325_POWER_CTRL1_BT_SHIFT 8
+#define ILI9325_POWER_CTRL1_BT_SHIFT 8
#define ILI9325_POWER_CTRL1_BT_MASK (7 << ILI9325_POWER_CTRL1_BT_SHIFT)
# define ILI9325_POWER_CTRL1_BT(n) ((uint16_t)(n) << ILI9325_POWER_CTRL1_BT_SHIFT)
#define ILI9325_POWER_CTRL1_SAP (1 << 12)