diff options
author | Gregory Nutt <gnutt@nuttx.org> | 2014-05-13 10:38:46 -0600 |
---|---|---|
committer | Gregory Nutt <gnutt@nuttx.org> | 2014-05-13 10:38:46 -0600 |
commit | e744f86727763c51c67790d8f98aedcd57d1048a (patch) | |
tree | bca1f9d107a5ffe470468c24657c512d402abbdc | |
parent | 1a02c15166a34eb61a272f20d024af38e8e10bf7 (diff) | |
download | nuttx-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/ChangeLog | 2 | ||||
-rw-r--r-- | nuttx/configs/sam4e-ek/Kconfig | 34 | ||||
-rw-r--r-- | nuttx/configs/sam4e-ek/include/board.h | 17 | ||||
-rw-r--r-- | nuttx/configs/sam4e-ek/src/Makefile | 4 | ||||
-rw-r--r-- | nuttx/configs/sam4e-ek/src/sam_ili9325.c | 1418 | ||||
-rw-r--r-- | nuttx/configs/sam4e-ek/src/sam_ili9523.c | 222 | ||||
-rw-r--r-- | nuttx/drivers/mtd/ramtron.c | 6 | ||||
-rw-r--r-- | nuttx/include/nuttx/lcd/ili9325.h | 10 |
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) |