diff --git a/configs/README.txt b/configs/README.txt index 51b7397217..ef4a3d43c6 100644 --- a/configs/README.txt +++ b/configs/README.txt @@ -522,6 +522,10 @@ defconfig -- This is a configuration file similar to the Linux By default, NX builds to use a framebuffer driver (see include/nuttx/fb.h). If this option is defined, NX will build to use an LCD driver (see include/nuttx/lcd.h). + CONFIG_LCD_MAXPOWER - The full-on power setting for an LCD + device. + CONFIG_LCD_MAXCONTRAST - The maximum contrast value for an + LCD device. CONFIG_NX_MOUSE Build in support for mouse input. CONFIG_NX_KBD diff --git a/configs/sam3u-ek/nx/defconfig b/configs/sam3u-ek/nx/defconfig index 6cbc5c7303..9ad79eeaf2 100755 --- a/configs/sam3u-ek/nx/defconfig +++ b/configs/sam3u-ek/nx/defconfig @@ -664,6 +664,8 @@ CONFIG_USBSTRG_REMOVABLE=y # By default, NX builds to use a framebuffer driver (see # include/nuttx/fb.h). If this option is defined, NX will # build to use an LCD driver (see include/nuttx/lcd.h). +# CONFIG_LCD_MAXPOWER - The full-on power setting for an LCD device. +# CONFIG_LCD_MAXCONTRAST - The maximum contrast value for an LCD device. # CONFIG_NX_MOUSE # Build in support for mouse input # CONFIG_NX_KBD @@ -711,6 +713,8 @@ CONFIG_NX_DISABLE_24BPP=y CONFIG_NX_DISABLE_32BPP=y CONFIG_NX_PACKEDMSFIRST=n CONFIG_NX_LCDDRIVER=y +CONFIG_LCD_MAXPOWER=31 +CONFIG_LCD_MAXCONTRAST=1 CONFIG_NX_MOUSE=n CONFIG_NX_KBD=n #CONFIG_NXTK_BORDERWIDTH=4 diff --git a/configs/sam3u-ek/src/sam3uek_internal.h b/configs/sam3u-ek/src/sam3uek_internal.h index fe2bd9c1a8..1e79a86f1e 100755 --- a/configs/sam3u-ek/src/sam3uek_internal.h +++ b/configs/sam3u-ek/src/sam3uek_internal.h @@ -57,6 +57,11 @@ #define LCD_BASE SAM3U_EXTCS2_BASE +/* Touchscreen controller (TSC) */ + +#define CONFIG_TSC_ADS7843 1 /* ADS7843 present on board */ +#define CONFIG_TSC_SPI 0 /* On SPI0 */ + /* SAM3U-EK GPIO Pin Definitions ****************************************************/ /* LCD: @@ -131,6 +136,11 @@ #define GPIO_LCD_BKL (GPIO_OUTPUT|GPIO_CFG_DEFAULT|GPIO_OUTPUT_CLEAR|GPIO_PORT_PIOC|GPIO_PIN19) +/* Touchscreen controller (TSC) */ + +#define GPIO_TCS_IRQ (PIO_INPUT|GPIO_CFG_PULLUP|GPIO_PORT_PIOA|GPIO_PIN6) +#define GPIO_TCS_BUSY (PIO_INPUT|GPIO_CFG_PULLUP|GPIO_PORT_PIOA|GPIO_PIN6) + /* LEDs */ #define GPIO_LED0 (GPIO_OUTPUT|GPIO_CFG_DEFAULT|GPIO_PORT_PIOB|GPIO_OUTPUT_CLEAR|GPIO_PIN0) @@ -151,6 +161,10 @@ /* SPI Chip Selects */ +/* Chip select pin connected to the touchscreen controller. */ + +#define GPIO_TSC_NPCS GPIO_SPI0_NPCS2_PC14 + /************************************************************************************ * Public Types ************************************************************************************/ diff --git a/configs/sam3u-ek/src/up_lcd.c b/configs/sam3u-ek/src/up_lcd.c index b1873326ab..ec08749a0e 100755 --- a/configs/sam3u-ek/src/up_lcd.c +++ b/configs/sam3u-ek/src/up_lcd.c @@ -114,11 +114,13 @@ #include #include #include +#include #include #include #include #include +#include #include @@ -132,6 +134,20 @@ * Pre-processor Definitions **************************************************************************************/ +/* CONFIG_LCD_MAXCONTRAST -- must be defined and less than 32 */ + +#if !defined(CONFIG_LCD_MAXCONTRAST) || CONFIG_LCD_MAXCONTRAST < 1 || CONFIG_LCD_MAXCONTRAST > 31 +# error "CONFIG_LCD_MAXCONTRAST must be defined in the range 1 to 31" +#endif + +/* Configuration **********************************************************************/ + +#ifndef CONFIG_DEBUG +# undef CONFIG_DEBUG_GRAPHICS +#endif + +/* Graphics Capbilities ***************************************************************/ + /* LCD resolution */ #define SAM3UEK_XRES 320 @@ -142,10 +158,119 @@ #define SAM3UEK_BPP 16 #define SAM3UEK_RGBFMT FB_FMT_RGB16_565 +/* HX834x Definitions ****************************************************************/ + /* HX834x register select */ #define HX843X_LCD_RS (1 << 1) +/* HX8347 ID code */ + +#define HX8347_CHIPID 0x47 + +/* HX8347 LCD Registers */ + +#define HX8347_R00H 0x00 +#define HX8347_R01H 0x01 +#define HX8347_R02H 0x02 +#define HX8347_R03H 0x03 +#define HX8347_R04H 0x04 +#define HX8347_R05H 0x05 +#define HX8347_R06H 0x06 +#define HX8347_R07H 0x07 +#define HX8347_R08H 0x08 +#define HX8347_R09H 0x09 +#define HX8347_R0AH 0x0a +#define HX8347_R0CH 0x0c +#define HX8347_R0DH 0x0d +#define HX8347_R0EH 0x0e +#define HX8347_R0FH 0x0f +#define HX8347_R10H 0x10 +#define HX8347_R11H 0x11 +#define HX8347_R12H 0x12 +#define HX8347_R13H 0x13 +#define HX8347_R14H 0x14 +#define HX8347_R15H 0x15 +#define HX8347_R16H 0x16 +#define HX8347_R18H 0x18 +#define HX8347_R19H 0x19 +#define HX8347_R1AH 0x1a +#define HX8347_R1BH 0x1b +#define HX8347_R1CH 0x1c +#define HX8347_R1DH 0x1d +#define HX8347_R1EH 0x1e +#define HX8347_R1FH 0x1f +#define HX8347_R20H 0x20 +#define HX8347_R21H 0x21 +#define HX8347_R22H 0x22 +#define HX8347_R23H 0x23 +#define HX8347_R24H 0x24 +#define HX8347_R25H 0x25 +#define HX8347_R26H 0x26 +#define HX8347_R27H 0x27 +#define HX8347_R28H 0x28 +#define HX8347_R29H 0x29 +#define HX8347_R2AH 0x2a +#define HX8347_R2BH 0x2b +#define HX8347_R2CH 0x2c +#define HX8347_R2DH 0x2d +#define HX8347_R35H 0x35 +#define HX8347_R36H 0x36 +#define HX8347_R37H 0x37 +#define HX8347_R38H 0x38 +#define HX8347_R39H 0x39 +#define HX8347_R3AH 0x3a +#define HX8347_R3BH 0x3b +#define HX8347_R3CH 0x3c +#define HX8347_R3DH 0x3d +#define HX8347_R3EH 0x3e +#define HX8347_R40H 0x40 +#define HX8347_R41H 0x41 +#define HX8347_R42H 0x42 +#define HX8347_R43H 0x43 +#define HX8347_R44H 0x44 +#define HX8347_R45H 0x45 +#define HX8347_R46H 0x46 +#define HX8347_R47H 0x47 +#define HX8347_R48H 0x48 +#define HX8347_R49H 0x49 +#define HX8347_R4AH 0x4a +#define HX8347_R4BH 0x4b +#define HX8347_R4CH 0x4c +#define HX8347_R4DH 0x4d +#define HX8347_R4EH 0x4e +#define HX8347_R4FH 0x4f +#define HX8347_R50H 0x50 +#define HX8347_R51H 0x51 +#define HX8347_R64H 0x64 +#define HX8347_R65H 0x65 +#define HX8347_R66H 0x66 +#define HX8347_R67H 0x67 +#define HX8347_R70H 0x70 +#define HX8347_R72H 0x72 +#define HX8347_R90H 0x90 +#define HX8347_R91H 0x91 +#define HX8347_R93H 0x93 +#define HX8347_R94H 0x94 +#define HX8347_R95H 0x95 + +/************************************************************************************** + * Private Type Definition + **************************************************************************************/ + +/* This structure describes the state of this driver */ + +struct sam3u_dev_s +{ + /* Publically visible device structure */ + + struct lcd_dev_s dev; + + /* Private device state */ + + uint8_t power; /* The current power setting */ +}; + /************************************************************************************** * Private Function Protototypes **************************************************************************************/ @@ -155,6 +280,21 @@ static void sam3u_putreg(uint16_t reg, uint16_t data); static uint16_t sam3u_getreg(uint16_t reg); +/* Misc. LCD Helper Functions */ + +static void sam3u_setcursor(fb_coord_t x, fb_coord_t y); +static inline void sam3u_wrsetup(void); +static inline void sam3u_wrram(uint16_t color); +static inline uint16_t sam3u_rdram(void); +static void sam3u_lcdon(void); +static void sam3u_lcdoff(void); + +#ifdef CONFIG_DEBUG_GRAPHICS +static void sam3u_dumpreg(uint8_t startreg, uint8_t endreg); +#else +# define sam3u_dumpreg(startreg,endreg) +#endif + /* LCD Data Transfer Methods */ static int sam3u_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer, @@ -207,7 +347,7 @@ static uint16_t g_runbuffer[SAM3UEK_XRES]; /* This structure describes the overall LCD video controller */ -static struct fb_videoinfo_s g_videoinfo = +static const struct fb_videoinfo_s g_videoinfo = { .fmt = SAM3UEK_RGBFMT, /* Color format: RGB16-565: RRRR RGGG GGGB BBBB */ .xres = SAM3UEK_XRES, /* Horizontal resolution in pixel columns */ @@ -217,7 +357,7 @@ static struct fb_videoinfo_s g_videoinfo = /* This is the standard, NuttX Plane information object */ -static struct lcd_planeinfo_s g_planeinfo = +static const struct lcd_planeinfo_s g_planeinfo = { .putrun = sam3u_putrun, /* Put a run into LCD memory */ .getrun = sam3u_getrun, /* Get a run from LCD memory */ @@ -227,22 +367,25 @@ static struct lcd_planeinfo_s g_planeinfo = /* This is the standard, NuttX LCD driver object */ -static struct lcd_dev_s g_lcddev_s = +static struct sam3u_dev_s g_lcddev_s = { - /* LCD Configuration */ + .dev = + { + /* LCD Configuration */ - .getvideoinfo = sam3u_getvideoinfo, - .getplaneinfo = sam3u_getplaneinfo, + .getvideoinfo = sam3u_getvideoinfo, + .getplaneinfo = sam3u_getplaneinfo, - /* LCD RGB Mapping -- Not supported */ - /* Cursor Controls -- Not supported */ + /* LCD RGB Mapping -- Not supported */ + /* Cursor Controls -- Not supported */ - /* LCD Specific Controls */ + /* LCD Specific Controls */ - .getpower = sam3u_getpower, - .setpower = sam3u_setpower, - .getcontrast = sam3u_getcontrast, - .setcontrast = sam3u_setcontrast, + .getpower = sam3u_getpower, + .setpower = sam3u_setpower, + .getcontrast = sam3u_getcontrast, + .setcontrast = sam3u_setcontrast, + }, }; /************************************************************************************** @@ -277,6 +420,128 @@ static uint16_t sam3u_getreg(uint16_t reg) return getreg16(LCD_BASE + HX843X_LCD_RS); } +/************************************************************************************** + * Name: sam3u_setcursor + * + * Description: + * Set the LCD cursor position. + * + **************************************************************************************/ + +static void sam3u_setcursor(fb_coord_t x, fb_coord_t y) +{ + uint8_t x1; + uint8_t x2; + uint8_t y1; + uint8_t y2; + + x1 = (uint8_t) x & 0xff; + x2 = ((uint16_t)x & 0xff00) >> 8; + y1 = (uint8_t) y & 0xff; + y2 = ((uint16_t)y & 0xff00) >> 8; + + sam3u_putreg(HX8347_R02H, x2); /* column high */ + sam3u_putreg(HX8347_R03H, x1); /* column low */ + sam3u_putreg(HX8347_R06H, y2); /* row high */ + sam3u_putreg(HX8347_R07H, y1); /* row low */ +} + +/************************************************************************************** + * Name: sam3u_wrsetup + * + * Description: + * Set up for a GRAM write operation. + * + **************************************************************************************/ + +static inline void sam3u_wrsetup(void) +{ + putreg16(HX8347_R22H, LCD_BASE); +} + +/************************************************************************************** + * Name: sam3u_wrram + * + * Description: + * Write to the 16-bit GRAM register + * + **************************************************************************************/ + +static inline void sam3u_wrram(uint16_t color) +{ + putreg16(color, LCD_BASE + HX843X_LCD_RS); +} + +/************************************************************************************** + * Name: sam3u_rdram + * + * Description: + * Read from the 16-bit GRAM register + * + **************************************************************************************/ + +static inline uint16_t sam3u_rdram(void) +{ + return getreg16(LCD_BASE + HX843X_LCD_RS); +} + +/************************************************************************************** + * Name: sam3u_lcdon + * + * Description: + * Turn the LCD on + * + **************************************************************************************/ + +static void sam3u_lcdon(void) +{ + /* Display ON Setting */ + + sam3u_putreg(HX8347_R90H, 0x7f); /* SAP=0111 1111 */ + sam3u_putreg(HX8347_R26H, 0x04); /* GON=0 DTE=0 D=01 */ + up_mdelay(100); + sam3u_putreg(HX8347_R26H, 0x24); /* GON=1 DTE=0 D=01 */ + sam3u_putreg(HX8347_R26H, 0x2c); /* GON=1 DTE=0 D=11 */ + up_mdelay(100); + sam3u_putreg(HX8347_R26H, 0x3c); /* GON=1 DTE=1 D=11 */ +} + +/************************************************************************************** + * Name: sam3u_lcdoff + * + * Description: + * Turn the LCD off + * + **************************************************************************************/ + +static void sam3u_lcdoff(void) +{ + sam3u_putreg(HX8347_R90H, 0x00); /* SAP=0000 0000 */ + sam3u_putreg(HX8347_R26H, 0x00); /* GON=0 DTE=0 D=00 */ +} + +/************************************************************************************** + * Name: sam3u_dumpreg + * + * Description: + * Dump a range of LCD registers. + * + **************************************************************************************/ + +#ifdef CONFIG_DEBUG_GRAPHICS +static void sam3u_dumpreg(uint8_t startreg, uint8_t endreg) +{ + uint16_t value; + uint8_t addr; + + for (addr = startreg; addr <= endreg; addr++) + { + value = sam3u_getreg(addr); + printf("LCD %02x = %04x\n", addr, value); + } +} +#endif + /************************************************************************************** * Name: sam3u_putrun * @@ -294,7 +559,25 @@ static uint16_t sam3u_getreg(uint16_t reg) static int sam3u_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer, size_t npixels) { - return -ENOSYS; + uint16_t *run = (uint16_t*)buffer; + unsigned int i; + + /* Buffer must be provided and aligned to a 16-bit address boundary */ + + DEBUGASSERT(buffer && ((uintptr_t)buffer & 1) == 0); + + /* Set up for the write */ + + sam3u_setcursor(row, col); + sam3u_wrsetup(); + + /* Write the run to GRAM */ + + for (i = 0; i < npixels; i++) + { + sam3u_wrram(*run++); + } + return OK; } /************************************************************************************** @@ -314,7 +597,24 @@ static int sam3u_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffe static int sam3u_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer, size_t npixels) { - return -ENOSYS; + uint16_t *run = (uint16_t*)buffer; + unsigned int i; + + /* Buffer must be provided and aligned to a 16-bit address boundary */ + + DEBUGASSERT(buffer && ((uintptr_t)buffer & 1) == 0); + + /* Set up for the read */ + + sam3u_setcursor(row, col); + + /* Read the run from GRAM */ + + for (i = 0; i < npixels; i++) + { + sam3u_wrram(*run++); + } + return OK; } /************************************************************************************** @@ -328,7 +628,9 @@ static int sam3u_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer, static int sam3u_getvideoinfo(FAR struct lcd_dev_s *dev, FAR struct fb_videoinfo_s *vinfo) { - return -ENOSYS; + DEBUGASSERT(dev && vinfo); + memcpy(vinfo, &g_videoinfo, sizeof(struct fb_videoinfo_s)); + return OK; } /************************************************************************************** @@ -342,35 +644,71 @@ static int sam3u_getvideoinfo(FAR struct lcd_dev_s *dev, static int sam3u_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planeno, FAR struct lcd_planeinfo_s *pinfo) { - return -ENOSYS; + DEBUGASSERT(dev && pinfo); + memcpy(pinfo, &g_planeinfo, sizeof(struct lcd_planeinfo_s)); + return OK; } /************************************************************************************** * Name: sam3u_getpower * * Description: - * Get the LCD panel power status (0: full off - CONFIG_LCD_MAXPOWER: - * full on. + * 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 sam3u_getpower(struct lcd_dev_s *dev) { - return -ENOSYS; + struct sam3u_dev_s *priv = (struct sam3u_dev_s *)dev; + DEBUGASSERT(dev); + return priv->power; } /************************************************************************************** * Name: sam3u_setpower * * Description: - * Enable/disable LCD panel power (0: full off - CONFIG_LCD_MAXPOWERL: - * full on). + * Enable/disable LCD panel power (0: full off - CONFIG_LCD_MAXPOWERL: full on). On + * backlit LCDs, this setting may correspond to the backlight setting. + * + * LCD backlight is made of 4 white chip LEDs in parallel, driven by an AAT3194 charge + * pump, MN4. The AAT3194 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. * **************************************************************************************/ static int sam3u_setpower(struct lcd_dev_s *dev, int power) { - return -ENOSYS; + struct sam3u_dev_s *priv = (struct sam3u_dev_s *)dev; + unsigned int i; + + DEBUGASSERT(power <= CONFIG_LCD_MAXPOWER); + + /* Switch off backlight */ + + sam3u_gpiowrite(GPIO_LCD_BKL, false); + + /* For for at least 500uS to drain the charge pump */ + + up_udelay(500); + + /* Set new backlight level by pumping "level" times */ + + for (i = 0; i < power; i++) + { + sam3u_gpiowrite(GPIO_LCD_BKL, false); + sam3u_gpiowrite(GPIO_LCD_BKL, false); + sam3u_gpiowrite(GPIO_LCD_BKL, false); + sam3u_gpiowrite(GPIO_LCD_BKL, true);; + sam3u_gpiowrite(GPIO_LCD_BKL, true);; + sam3u_gpiowrite(GPIO_LCD_BKL, true);; + } + + priv->power = power; + return OK; } /************************************************************************************** @@ -407,14 +745,22 @@ static int sam3u_setcontrast(struct lcd_dev_s *dev, unsigned int contrast) * Name: up_lcdinitialize * * Description: - * Initialize the LCD video hardware. + * 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) { +#ifdef CONFIG_DEBUG_GRAPHICS + uint16_t hxregval; +#endif uint32_t regval; - + unsigned int i; + + gvdbg("Initializing\n"); + /* Enable LCD EXTCS2 pins */ sam3u_configgpio(GPIO_LCD_NCS2); @@ -450,22 +796,118 @@ int up_lcdinitialize(void) /* Configure SMC CS2 */ regval = (4 << SMCCS_SETUP_NWESETUP_SHIFT) | (2 << SMCCS_SETUP_NCSWRSETUP_SHIFT) | - (4 << SMCCS_SETUP_NRDSETUP_SHIFT) | (2 << SMCCS_SETUP_NCSRDSETUP_SHIFT); + (4 << SMCCS_SETUP_NRDSETUP_SHIFT) | (2 << SMCCS_SETUP_NCSRDSETUP_SHIFT); putreg32(regval, SAM3U_SMCCS_SETUP(2)); regval = (5 << SMCCS_PULSE_NWEPULSE_SHIFT) | (18 << SMCCS_PULSE_NCSWRPULSE_SHIFT) | - (5 << SMCCS_PULSE_RDPULSE_SHIFT) | (18 << SMCCS_PULSE_NCSRDPULSE_SHIFT); + (5 << SMCCS_PULSE_RDPULSE_SHIFT) | (18 << SMCCS_PULSE_NCSRDPULSE_SHIFT); putreg32(regval, SAM3U_SMCCS_PULSE(2)); regval = (22 << SMCCS_CYCLE_NWECYCLE_SHIFT) | (22 << SMCCS_CYCLE_NRDCYCLE_SHIFT); putreg32(regval, SAM3U_SMCCS_CYCLE(2)); - regval = getreg32(SAM3U_SMCCS_MODE(2)); + regval = getreg32(SAM3U_SMCCS_MODE(2)); regval &= ~(SMCCS_MODE_DBW_MASK | SMCCS_MODE_PMEN); regval |= (SMCCS_MODE_READMODE) | (SMCCS_MODE_WRITEMODE) | (SMCCS_MODE_DBW_16BITS); putreg32(regval, SAM3U_SMCCS_MODE(2)); - return -ENOSYS; + /* Check HX8347 Chip ID */ + +#ifdef CONFIG_DEBUG_GRAPHICS + hxregval = sam3u_getreg(HX8347_R67H); + gvdbg("HX8347 chip ID: %04x\n", hxregval); + if (hxregval != HX8347_CHIPID) + { + gdbg("Bad HX8347 chip ID: %04x\n", hxregval); + return -ENODEV; + } +#endif + + /* Initialize LCD controller (HX8347) -- Magic code from Atmel LCD example */ + + /* Start internal OSC */ + + sam3u_putreg(HX8347_R19H, 0x49); /* OSCADJ=10 0000 OSD_EN=1 60Hz */ + sam3u_putreg(HX8347_R93H, 0x0C); /* RADJ=1100 */ + + /* Power on flow */ + + sam3u_putreg(HX8347_R44H, 0x4D); /* VCM=100 1101 */ + sam3u_putreg(HX8347_R45H, 0x11); /* VDV=1 0001 */ + sam3u_putreg(HX8347_R20H, 0x40); /* BT=0100 */ + sam3u_putreg(HX8347_R1DH, 0x07); /* VC1=111 */ + sam3u_putreg(HX8347_R1EH, 0x00); /* VC3=000 */ + sam3u_putreg(HX8347_R1FH, 0x04); /* VRH=0100 */ + sam3u_putreg(HX8347_R1CH, 0x04); /* AP=100 */ + sam3u_putreg(HX8347_R1BH, 0x10); /* GASENB=0 PON=1 DK=0 XDK=0 DDVDH_TRI=0 STB=0 */ + up_mdelay(50); + sam3u_putreg(HX8347_R43H, 0x80); /* Set VCOMG=1 */ + up_mdelay(50); + + /* Gamma for CMO 2.8 */ + + sam3u_putreg(HX8347_R46H, 0x95); + sam3u_putreg(HX8347_R47H, 0x51); + sam3u_putreg(HX8347_R48H, 0x00); + sam3u_putreg(HX8347_R49H, 0x36); + sam3u_putreg(HX8347_R4AH, 0x11); + sam3u_putreg(HX8347_R4BH, 0x66); + sam3u_putreg(HX8347_R4CH, 0x14); + sam3u_putreg(HX8347_R4DH, 0x77); + sam3u_putreg(HX8347_R4EH, 0x13); + sam3u_putreg(HX8347_R4FH, 0x4c); + sam3u_putreg(HX8347_R50H, 0x46); + sam3u_putreg(HX8347_R51H, 0x46); + + /* 240x320 window setting */ + + sam3u_putreg(HX8347_R02H, 0x00); /* Column address start2 */ + sam3u_putreg(HX8347_R03H, 0x00); /* Column address start1 */ + sam3u_putreg(HX8347_R04H, 0x00); /* Column address end2 */ + sam3u_putreg(HX8347_R05H, 0xef); /* Column address end1 */ + sam3u_putreg(HX8347_R06H, 0x00); /* Row address start2 */ + sam3u_putreg(HX8347_R07H, 0x00); /* Row address start1 */ + sam3u_putreg(HX8347_R08H, 0x01); /* Row address end2 */ + sam3u_putreg(HX8347_R09H, 0x3f); /* Row address end1 */ + + /* Display Setting */ + + sam3u_putreg(HX8347_R01H, 0x06); /* IDMON=0 INVON=1 NORON=1 PTLON=0 */ + sam3u_putreg(HX8347_R16H, 0xc8); /* MY=1 MX=1 MV=0 BGR=1 */ + sam3u_putreg(HX8347_R23H, 0x95); /* N_DC=1001 0101 */ + sam3u_putreg(HX8347_R24H, 0x95); /* P_DC=1001 0101 */ + sam3u_putreg(HX8347_R25H, 0xff); /* I_DC=1111 1111 */ + sam3u_putreg(HX8347_R27H, 0x06); /* N_BP=0000 0110 */ + sam3u_putreg(HX8347_R28H, 0x06); /* N_FP=0000 0110 */ + sam3u_putreg(HX8347_R29H, 0x06); /* P_BP=0000 0110 */ + sam3u_putreg(HX8347_R2AH, 0x06); /* P_FP=0000 0110 */ + sam3u_putreg(HX8347_R2CH, 0x06); /* I_BP=0000 0110 */ + sam3u_putreg(HX8347_R2DH, 0x06); /* I_FP=0000 0110 */ + sam3u_putreg(HX8347_R3AH, 0x01); /* N_RTN=0000 N_NW=001 */ + sam3u_putreg(HX8347_R3BH, 0x01); /* P_RTN=0000 P_NW=001 */ + sam3u_putreg(HX8347_R3CH, 0xf0); /* I_RTN=1111 I_NW=000 */ + sam3u_putreg(HX8347_R3DH, 0x00); /* DIV=00 */ + sam3u_putreg(HX8347_R3EH, 0x38); /* SON=38h */ + sam3u_putreg(HX8347_R40H, 0x0f); /* GDON=0Fh */ + sam3u_putreg(HX8347_R41H, 0xf0); /* GDOF=F0h */ + + /* Set LCD backlight to FULL off */ + + sam3u_setpower(&g_lcddev_s.dev, LCD_FULL_OFF); + + /* Fill the display memory with the color BLACK */ + + sam3u_setcursor(0, 0); + sam3u_wrsetup(); + for (i = 0; i < (SAM3UEK_XRES * SAM3UEK_YRES); i++) + { + sam3u_wrram(RGB16_BLACK); + } + + /* Turn the LCD on (but with the backlight off) */ + + sam3u_lcdon(); + return OK; } /************************************************************************************** @@ -477,9 +919,10 @@ int up_lcdinitialize(void) * **************************************************************************************/ -FAR struct lcd_dev_s *up_lcdgetdev(int lcdddev) +FAR struct lcd_dev_s *up_lcdgetdev(int lcddev) { - return NULL; + gvdbg("lcddev: %d\n", lcddev); + return lcddev == 0 ? &g_lcddev_s.dev : NULL; } /************************************************************************************** @@ -492,6 +935,17 @@ FAR struct lcd_dev_s *up_lcdgetdev(int lcdddev) void up_lcduninitialize(void) { + /* Turn the LCD off */ + + sam3u_lcdoff(); + + /* Set LCD backlight to FULL off */ + + sam3u_setpower(&g_lcddev_s.dev, LCD_FULL_OFF); + + /* Disable SMC peripheral clock */ + + putreg32((1 << SAM3U_PID_SMC), SAM3U_PMC_PCDR); }