Support for Sharp Memory LCD. From Librae

This commit is contained in:
Gregory Nutt 2013-12-23 16:03:54 -06:00
parent 1c61bb0c53
commit 45d2bf2554
5 changed files with 970 additions and 1 deletions

View File

@ -21,7 +21,7 @@ config LCD_NOGETRUN
config LCD_MAXCONTRAST
int "LCD maximum contrast"
default 63 if NOKIA6100_S1D15G10
default 63 if NOKIA6100_S1D15G10 || LCD_SHARP_MEMLCD
default 127 if NOKIA6100_PCF8833
default 255 if LCD_P14201 || LCD_LCD1602
default 63
@ -433,6 +433,56 @@ config SSD1289_PROFILE3
endchoice
endif
config LCD_SHARP_MEMLCD
bool "Sharp Memory LCD Suite"
default n
---help---
memlcd.c. Driver for Sharp Memory LCD Suite.
if LCD_SHARP_MEMLCD
choice MEMLCD_MODEL
prompt "Choose Model"
default MEMLCD_LS013B7DH03
config MEMLCD_LS013B7DH01
bool "LS013B7DH01"
---help---
Selects the LS013B7DH01 model
config MEMLCD_LS013B7DH03
bool "LS013B7DH03"
---help---
Selects the LS013B7DH03 model
endchoice
config MEMLCD_NINTERFACES
int "Number of physical Memory LCD devices"
default 1
range 1 1
---help---
Specifies the number of physical Memory LCD devices that will
be supported.
config MEMLCD_EXTCOMIN_MODE_HW
bool "Use hardware mode for EXTCOMIN"
default n
---help---
If use hardware mode to toggle VCOM, we need to send specific
command at a constant frequency to trigger the LCD intenal
hardware logic. While use software mode, we set up a timer to
toggle EXTCOMIN connected IO, basically, it is a hardware
timer to ensure a constant frequency.
config MEMLCD_SPI_FREQUENCY
int "SPI frequency"
default 3500000
---help---
Define to use a different bus frequency, FIXME DEFAULT VALUE OK?
endif
choice
prompt "LCD Orientation"
default LCD_LANDSCAPE

View File

@ -71,6 +71,10 @@ ifeq ($(CONFIG_LCD_ST7567),y)
CSRCS += st7567.c
endif
ifeq ($(CONFIG_LCD_SHARP_MEMLCD),y)
CSRCS += memlcd.c
endif
# Include LCD driver build support
DEPPATH += --dep-path lcd

View File

@ -108,6 +108,12 @@ Re-usable LCD drivers reside in the drivers/lcd directory:
st7567.c. LCD Display Module, ST7567, Univision Technology Inc. Used
with the LPCXpresso and Embedded Artists base board.
memlcd.c. Sharp Memory LCD Suite, LS013B7DH01, LS013B7DH03, etc.
There are some more different models, they are basically controlled
by similar logics, thus this driver can be extended. Example usage:
configs/maple
OLEDs:
-----
p14201.c. Driver for RiT P14201 series display with SD1329 IC

779
drivers/lcd/memlcd.c Normal file
View File

@ -0,0 +1,779 @@
/******************************************************************************
* drivers/lcd/memlcd.c
* Driver for Sharp Memory LCD.
*
* Copyright (C) 2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
* Librae <librae8226@gmail.com>
*
* 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 writen permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
/******************************************************************************
* Included Files
******************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <errno.h>
#include <debug.h>
#include <nuttx/arch.h>
#include <nuttx/spi/spi.h>
#include <nuttx/lcd/lcd.h>
#include <nuttx/lcd/memlcd.h>
#include <arch/irq.h>
/******************************************************************************
* Pre-processor Definitions
******************************************************************************/
/* Configuration */
/* Cisplay resolution */
#if defined CONFIG_MEMLCD_LS013B7DH01
# define MEMLCD_XRES 144
# define MEMLCD_YRES 168
#elif defined CONFIG_MEMLCD_LS013B7DH03
# define MEMLCD_XRES 128
# define MEMLCD_YRES 128
#else
# error "This Memory LCD model is not supported yet."
#endif
/* lcd command */
#define MEMLCD_CMD_UPDATE (0x01)
#define MEMLCD_CMD_ALL_CLEAR (0x04)
#define MEMLCD_CONTROL_BYTES (0)
/* Dolor depth and format */
#define MEMLCD_BPP 1
#define MEMLCD_COLORFMT FB_FMT_Y1
/* Bytes per logical row and column */
#define MEMLCD_XSTRIDE (MEMLCD_XRES >> 3)
#define MEMLCD_YSTRIDE (MEMLCD_YRES >> 3)
/* display memory allocation */
#define MEMLCD_FBSIZE (MEMLCD_XSTRIDE*MEMLCD_YRES)
/* contrast setting, related to VCOM toggle frequency
* higher frequency gives better contrast, instead, saves power
*/
#define MEMLCD_CONTRAST 24
#define MEMLCD_MAXCONTRAST 60
#define MEMLCD_MINCONTRAST 1
/* Other misc settings */
#define MEMLCD_SPI_FREQUENCY 2250000
#define MEMLCD_SPI_BITS (-8)
#define MEMLCD_SPI_MODE SPIDEV_MODE0
#define LS_BIT (1 << 0)
#define MS_BIT (1 << 7)
/* Debug */
#ifdef CONFIG_DEBUG_LCD
# define lcddbg(format, arg...) dbg(format, ##arg)
# define lcdvdbg(format, arg...) vdbg(format, ##arg)
#else
# define lcddbg(x...)
# define lcdvdbg(x...)
#endif
/******************************************************************************
* Private Type Definition
******************************************************************************/
struct memlcd_dev_s
{
/* Publically visible device structure */
struct lcd_dev_s dev;
/* Private lcd-specific information follows */
FAR struct spi_dev_s *spi; /* Cached SPI device reference */
FAR struct memlcd_priv_s *priv; /* Board specific structure */
uint8_t contrast; /* Current contrast setting */
uint8_t power; /* Current power setting */
/* The memlcds does not support reading the display memory in SPI mode.
* Since there is 1 BPP and is byte access, it is necessary to keep a
* shadow copy of the framebuffer. At 128x128, it amounts to 2KB.
*/
uint8_t fb[MEMLCD_FBSIZE];
};
/******************************************************************************
* Private Function Protototypes
******************************************************************************/
/* Low-level spi helpers */
static inline void memlcd_configspi(FAR struct spi_dev_s *spi);
#ifdef CONFIG_SPI_OWNBUS
static inline void memlcd_select(FAR struct spi_dev_s *spi);
static inline void memlcd_deselect(FAR struct spi_dev_s *spi);
#else
static void memlcd_select(FAR struct spi_dev_s *spi);
static void memlcd_deselect(FAR struct spi_dev_s *spi);
#endif
/* lcd data transfer methods */
static int memlcd_putrun(fb_coord_t row, fb_coord_t col,
FAR const uint8_t * buffer, size_t npixels);
static int memlcd_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t * buffer,
size_t npixels);
/* lcd configuration */
static int memlcd_getvideoinfo(FAR struct lcd_dev_s *dev,
FAR struct fb_videoinfo_s *vinfo);
static int memlcd_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planeno,
FAR struct lcd_planeinfo_s *pinfo);
/* lcd specific controls */
static int memlcd_getpower(struct lcd_dev_s *dev);
static int memlcd_setpower(struct lcd_dev_s *dev, int power);
static int memlcd_getcontrast(struct lcd_dev_s *dev);
static int memlcd_setcontrast(struct lcd_dev_s *dev, unsigned int contrast);
/******************************************************************************
* Private Data
******************************************************************************/
static uint8_t g_runbuffer[MEMLCD_BPP * MEMLCD_XRES / 8];
/* This structure describes the overall lcd video controller */
static const struct fb_videoinfo_s g_videoinfo =
{
.fmt = MEMLCD_COLORFMT, /* Color format: rgb16-565: rrrr rggg gggb bbbb */
.xres = MEMLCD_XRES, /* Horizontal resolution in pixel columns */
.yres = MEMLCD_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 = memlcd_putrun, /* Put a run into lcd memory */
.getrun = memlcd_getrun, /* Get a run from lcd memory */
.buffer = (uint8_t *) g_runbuffer, /* Run scratch buffer */
.bpp = MEMLCD_BPP, /* Bits-per-pixel */
};
/* This is the oled driver instance (only a single device is supported for now) */
static struct memlcd_dev_s g_memlcddev =
{
.dev =
{
/* lcd configuration */
.getvideoinfo = memlcd_getvideoinfo,
.getplaneinfo = memlcd_getplaneinfo,
/* lcd specific controls */
.getpower = memlcd_getpower,
.setpower = memlcd_setpower,
.getcontrast = memlcd_getcontrast,
.setcontrast = memlcd_setcontrast,
},
};
/******************************************************************************
* Private Functions
******************************************************************************/
/******************************************************************************
* __set_bit - Set a bit in memory
*
* @nr: the bit to set
* @addr: the address to start counting from
*
* Unlike set_bit(), this function is non-atomic and may be reordered.
* If it's called on the same region of memory simultaneously, the effect
* may be that only one operation succeeds.
*
******************************************************************************/
#define BIT(nr) (1 << (nr))
#define BITS_PER_BYTE 8
#define BIT_MASK(nr) (1 << ((nr) % BITS_PER_BYTE))
#define BIT_BYTE(nr) ((nr) / BITS_PER_BYTE)
static inline void __set_bit(int nr, uint8_t * addr)
{
uint8_t mask = BIT_MASK(nr);
uint8_t *p = ((uint8_t *) addr) + BIT_BYTE(nr);
*p |= mask;
}
static inline void __clear_bit(int nr, uint8_t * addr)
{
uint8_t mask = BIT_MASK(nr);
uint8_t *p = ((uint8_t *) addr) + BIT_BYTE(nr);
*p &= ~mask;
}
static inline int __test_bit(int nr, const volatile uint8_t * addr)
{
return 1 & (addr[BIT_BYTE(nr)] >> (nr & (BITS_PER_BYTE - 1)));
}
/******************************************************************************
* Name: memlcd_configspi
*
* Description:
* Configure the SPI for use with the Sharp Memory LCD
*
* Input Parameters:
* spi - Reference to the SPI driver structure
*
* Returned Value:
* None
*
* Assumptions:
*
******************************************************************************/
static inline void memlcd_configspi(FAR struct spi_dev_s *spi)
{
#ifdef CONFIG_MEMLCD_SPI_FREQUENCY
lcddbg("Mode: %d Bits: %d Frequency: %d\n",
MEMLCD_SPI_MODE, MEMLCD_SPI_BITS, CONFIG_MEMLCD_SPI_FREQUENCY);
#else
lcddbg("Mode: %d Bits: %d Frequency: %d\n",
MEMLCD_SPI_MODE, MEMLCD_SPI_BITS, MEMLCD_SPI_FREQUENCY);
#endif
/* Configure SPI for the Memory LCD. But only if we own the SPI bus.
* Otherwise, don't bother because it might change.
*/
#ifdef CONFIG_SPI_OWNBUS
SPI_SETMODE(spi, MEMLCD_SPI_MODE);
SPI_SETBITS(spi, MEMLCD_SPI_BITS);
# ifdef CONFIG_MEMLCD_SPI_FREQUENCY
SPI_SETFREQUENCY(spi, CONFIG_MEMLCD_SPI_FREQUENCY);
# else
SPI_SETFREQUENCY(spi, MEMLCD_SPI_FREQUENCY);
# endif
#endif
}
/*******************************************************************************
* Name: memlcd_select
*
* Description:
* Select the SPI, locking and re-configuring if necessary
*
* Input Parameters:
* spi - Reference to the SPI driver structure
*
* Returned Value:
* None
*
* Assumptions:
*
******************************************************************************/
#ifdef CONFIG_SPI_OWNBUS
static inline void memlcd_select(FAR struct spi_dev_s *spi)
{
/* we own the spi bus, so just select the chip */
SPI_SELECT(spi, SPIDEV_DISPLAY, true);
}
#else
static void memlcd_select(FAR struct spi_dev_s *spi)
{
/*
* Select memlcd (locking the SPI bus in case there are multiple
* devices competing for the SPI bus
*/
SPI_LOCK(spi, true);
SPI_SELECT(spi, SPIDEV_DISPLAY, true);
/*
* Now make sure that the SPI bus is configured for the memlcd (it
* might have gotten configured for a different device while unlocked)
*/
SPI_SETMODE(spi, MEMLCD_SPI_MODE);
SPI_SETBITS(spi, MEMLCD_SPI_BITS);
# ifdef CONFIG_MEMLCD_SPI_FREQUENCY
SPI_SETFREQUENCY(spi, CONFIG_MEMLCD_SPI_FREQUENCY);
# else
SPI_SETFREQUENCY(spi, MEMLCD_SPI_FREQUENCY);
# endif
}
#endif
/*******************************************************************************
* Name: memlcd_deselect
*
* Description:
* De-select the SPI
*
* Input Parameters:
* spi - Reference to the SPI driver structure
*
* Returned Value:
* None
*
* Assumptions:
*
******************************************************************************/
#ifdef CONFIG_SPI_OWNBUS
static inline void memlcd_deselect(FAR struct spi_dev_s *spi)
{
/* we own the spi bus, so just de-select the chip */
SPI_SELECT(spi, SPIDEV_DISPLAY, false);
}
#else
static void memlcd_deselect(FAR struct spi_dev_s *spi)
{
/* de-select memlcd and relinquish the spi bus. */
SPI_SELECT(spi, SPIDEV_DISPLAY, false);
SPI_LOCK(spi, false);
}
#endif
/*******************************************************************************
* Name: memlcd_clear
*
* Description:
* This method can be used to clear the entire display.
*
* Input Parameters:
* mlcd - Reference to private driver structure
*
* Assumptions:
*
******************************************************************************/
static inline void memlcd_clear(FAR struct memlcd_dev_s *mlcd)
{
uint16_t cmd = MEMLCD_CMD_ALL_CLEAR;
lcddbg("Clear display\n");
memlcd_select(mlcd->spi);
/* XXX Ensure 2us here */
SPI_SNDBLOCK(mlcd->spi, &cmd, 2);
/* XXX Ensure 6us here */
memlcd_deselect(mlcd->spi);
}
/*******************************************************************************
* Name: memlcd_extcominisr
*
* Description:
* This method enables/disables the polarity (VCOM) toggling behavior for
* the Memory LCD. Which is always used within setpower() call.
* Basically, the frequency shall be 1Hz~60Hz.
* If use hardware mode to toggle VCOM, we need to send specific command at a
* constant frequency to trigger the LCD intenal hardware logic.
* While use software mode, we set up a timer to toggle EXTCOMIN connected IO,
* basically, it is a hardware timer to ensure a constant frequency.
*
* Input Parameters:
* mlcd - Reference to private driver structure
*
* Assumptions:
* Board specific logic needs to be provided to support it.
*
******************************************************************************/
static int memlcd_extcominisr(int irq, FAR void *context)
{
static bool pol = 0;
struct memlcd_dev_s *mlcd = &g_memlcddev;
#ifdef CONFIG_MEMLCD_EXTCOMIN_MODE_HW
# error "CONFIG_MEMLCD_EXTCOMIN_MODE_HW unsupported yet!"
/*
* start a worker thread, do it in bottom half?
*/
#else
pol = !pol;
mlcd->priv->setpolarity(pol);
#endif
return OK;
}
/*******************************************************************************
* Name: memlcd_putrun
*
* Description:
* This method can be used to write a partial raster line to the LCD.
*
* Input Parameters:
* row - Starting row to write to (range: 0 <= row < yres)
* col - Starting column to write to (range: 0 <= col <= xres-npixels)
* buffer - The buffer containing the run to be writen to the LCD
* npixels - The number of pixels to write to the LCD
* (range: 0 < npixels <= xres-col)
*
******************************************************************************/
static int memlcd_putrun(fb_coord_t row, fb_coord_t col,
FAR const uint8_t * buffer, size_t npixels)
{
FAR struct memlcd_dev_s *mlcd = (FAR struct memlcd_dev_s *)&g_memlcddev;
uint16_t cmd;
uint8_t *p;
uint8_t *pfb;
uint8_t usrmask;
int i;
DEBUGASSERT(buffer);
lcdvdbg("row: %d col: %d npixels: %d\n", row, col, npixels);
#ifdef CONFIG_NX_PACKEDMSFIRST
usrmask = MS_BIT;
#else
usrmask = LS_BIT;
#endif
pfb = &mlcd->fb[row * MEMLCD_XSTRIDE];
p = pfb + (col >> 3);
for (i = 0; i < npixels; i++)
{
if ((*buffer & usrmask) != 0)
{
__set_bit(col % 8 + i, p);
}
else
{
__clear_bit(col % 8 + i, p);
}
#ifdef CONFIG_NX_PACKEDMSFIRST
if (usrmask == LS_BIT)
{
buffer++;
usrmask = MS_BIT;
}
else
{
usrmask >>= 1;
}
#else
if (usrmask == MS_BIT)
{
buffer++;
usrmask = LS_BIT;
}
else
{
usrmask <<= 1;
}
#endif
}
/* Need to adjust start row by one because Memory LCD starts counting
* lines from 1, while the display interface starts from 0.
*/
row++;
memlcd_select(mlcd->spi);
/* XXX Ensure 6us here */
cmd = MEMLCD_CMD_UPDATE | row << 8;
SPI_SNDBLOCK(mlcd->spi, &cmd, 2);
SPI_SNDBLOCK(mlcd->spi, pfb, MEMLCD_YRES / 8 + MEMLCD_CONTROL_BYTES);
cmd = 0xffff;
SPI_SNDBLOCK(mlcd->spi, &cmd, 2);
/* XXX Ensure 2us here */
memlcd_deselect(mlcd->spi);
return OK;
}
/*******************************************************************************
* Name: memlcd_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 memlcd_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t * buffer,
size_t npixels)
{
FAR struct memlcd_dev_s *mlcd = (FAR struct memlcd_dev_s *)&g_memlcddev;
uint8_t *p;
uint8_t *pfb;
uint8_t usrmask;
int i;
DEBUGASSERT(buffer);
lcdvdbg("row: %d col: %d npixels: %d\n", row, col, npixels);
#ifdef CONFIG_NX_PACKEDMSFIRST
usrmask = MS_BIT;
#else
usrmask = LS_BIT;
#endif
pfb = &mlcd->fb[row * MEMLCD_XSTRIDE];
p = pfb + (col >> 3);
for (i = 0; i < npixels; i++)
{
if (__test_bit(col % 8 + i, p))
{
*buffer |= usrmask;
}
else
{
*buffer &= ~usrmask;
}
#ifdef CONFIG_NX_PACKEDMSFIRST
if (usrmask == LS_BIT)
{
buffer++;
usrmask = MS_BIT;
}
else
{
usrmask >>= 1;
}
#else
if (usrmask == MS_BIT)
{
buffer++;
usrmask = LS_BIT;
}
else
{
usrmask <<= 1;
}
#endif
}
return OK;
}
/*******************************************************************************
* Name: memlcd_getvideoinfo
*
* Description:
* Get information about the LCD video controller configuration.
*
******************************************************************************/
static int memlcd_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: memlcd_getplaneinfo
*
* Description:
* Get information about the configuration of each LCD color plane.
*
******************************************************************************/
static int memlcd_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planeno,
FAR struct lcd_planeinfo_s *pinfo)
{
DEBUGASSERT(pinfo && planeno == 0);
lcdvdbg("planeno: %d bpp: %d\n", planeno, g_planeinfo.bpp);
memcpy(pinfo, &g_planeinfo, sizeof(struct lcd_planeinfo_s));
return OK;
}
/*******************************************************************************
* Name: memlcd_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 memlcd_getpower(FAR struct lcd_dev_s *dev)
{
FAR struct memlcd_dev_s *mlcd = (FAR struct memlcd_dev_s *)dev;
DEBUGASSERT(mlcd);
lcddbg("%d\n", mlcd->power);
return mlcd->power;
}
/*******************************************************************************
* Name: memlcd_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 memlcd_setpower(FAR struct lcd_dev_s *dev, int power)
{
struct memlcd_dev_s *mlcd = (struct memlcd_dev_s *)dev;
DEBUGASSERT(mlcd && (unsigned)power <= CONFIG_LCD_MAXPOWER && mlcd->spi);
lcddbg("%d\n", power);
mlcd->power = power;
if (power > 0)
{
mlcd->priv->dispcontrol(1);
memlcd_clear(mlcd);
}
else
{
mlcd->priv->dispcontrol(0);
}
return OK;
}
/*******************************************************************************
* Name: memlcd_getcontrast
*
* Description:
* Get the current contrast setting (0-CONFIG_LCD_MAXCONTRAST).
*
******************************************************************************/
static int memlcd_getcontrast(struct lcd_dev_s *dev)
{
struct memlcd_dev_s *mlcd = (struct memlcd_dev_s *)dev;
DEBUGASSERT(mlcd);
lcddbg("contrast: %d\n", mlcd->contrast);
return mlcd->contrast;
}
/*******************************************************************************
* Name: memlcd_setcontrast
*
* Description:
* Set LCD panel contrast (0-CONFIG_LCD_MAXCONTRAST).
*
******************************************************************************/
static int memlcd_setcontrast(struct lcd_dev_s *dev, unsigned int contrast)
{
struct memlcd_dev_s *mlcd = (struct memlcd_dev_s *)dev;
DEBUGASSERT(mlcd);
lcddbg("contrast: %d\n", contrast);
if (contrast > MEMLCD_MAXCONTRAST)
{
contrast = MEMLCD_MAXCONTRAST;
}
if (contrast < MEMLCD_MINCONTRAST)
{
contrast = MEMLCD_MINCONTRAST;
}
mlcd->contrast = contrast;
mlcd->priv->setvcomfreq(contrast);
return OK;
}
/*******************************************************************************
* Public Functions
******************************************************************************/
/*******************************************************************************
* Name: memlcd_initialize
*
* Description:
* Initialize the Sharp Memory LCD hardware. The initial state of the
* OLED is fully initialized, display memory cleared, and the OLED ready
* to use, but with the power setting at 0 (full off == sleep mode).
*
* Input Parameters:
*
* spi - A reference to the SPI driver instance.
* devno - A value in the range of 0 through CONFIG_memlcd_NINTERFACES-1.
* This allows support for multiple OLED devices.
*
* Returned Value:
*
* On success, this function returns a reference to the LCD object for
* the specified LCD. NULL is returned on any failure.
*
******************************************************************************/
FAR struct lcd_dev_s *memlcd_initialize(FAR struct spi_dev_s *spi,
FAR struct memlcd_priv_s *priv,
unsigned int devno)
{
FAR struct memlcd_dev_s *mlcd = &g_memlcddev;
DEBUGASSERT(spi && priv && devno == 0);
/* register board specific functions */
mlcd->priv = priv;
mlcd->spi = spi;
memlcd_configspi(spi);
mlcd->priv->attachirq(memlcd_extcominisr);
lcddbg("done\n");
return &mlcd->dev;
}

130
include/nuttx/lcd/memlcd.h Normal file
View File

@ -0,0 +1,130 @@
/*******************************************************************************
* include/nuttx/lcd/memlcd.h
* Common definitions for the Sharp Memory LCD driver
*
* Copyright (C) 2010 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
#ifndef __INCLUDE_NUTTX_MEMLCD_H
#define __INCLUDE_NUTTX_MEMLCD_H
/*******************************************************************************
* Included Files
******************************************************************************/
#include <stdbool.h>
#ifdef __cplusplus
# define EXTERN extern "C"
extern "C"
{
#else
# define EXTERN extern
#endif
/*******************************************************************************
* Pre-processor Definitions
******************************************************************************/
/*******************************************************************************
* Public Types
******************************************************************************/
/* A reference to a structure of this type must be passed to the initialization
* method. It provides some board-specific hooks used by driver to manage the
* timer and gpio (IRQ and DISP).
*
* Memory for this structure is provided by the caller. It is not copied
* by the driver and is presumed to persist while the driver is active.
*/
struct memlcd_priv_s
{
/* IRQ/GPIO access callbacks. These operations all hidden behind
* callbacks to isolate the Memory LCD driver from differences in GPIO
* interrupt handling by varying boards and MCUs.
*
* irqattach - Attach the driver interrupt handler to the GPIO interrupt
* If isr is NULL, detach and disable it.
* dispcontrol - Enable or disable the DISP pin and EXTCOMIN interrupt.
* setpolarity - Board specified method to set EXTCOMIN.
* Needed only when CONFIG_MEMLCD_EXTCOMIN_MODE_HW is not set.
* setvcomfreq - Set timer frequency for EXTCOMIN.
*/
int (*attachirq) (xcpt_t isr);
void (*dispcontrol) (bool on);
#ifndef CONFIG_MEMLCD_EXTCOMIN_MODE_HW
void (*setpolarity) (bool pol);
#endif
void (*setvcomfreq) (unsigned int freq);
};
/*******************************************************************************
* Public Data
******************************************************************************/
/*******************************************************************************
* Public Function Prototypes
******************************************************************************/
/*******************************************************************************
* Name: memlcd_initialize
*
* Description:
*
* Input Parameters:
*
* spi - A reference to the SPI driver instance.
* devno - A value in the range of 0 throuh CONFIG_MEMLCD_NINTERFACES-1.
* This allows support for multiple devices.
* memlcd_priv_s - Board specific structure
*
* Returned Value:
*
* On success, this function returns a reference to the LCD object for the
* specified LCD. NULL is returned on any failure.
*
******************************************************************************/
struct lcd_dev_s; /* see nuttx/lcd.h */
struct spi_dev_s; /* see nuttx/spi/spi.h */
FAR struct lcd_dev_s *memlcd_initialize(FAR struct spi_dev_s *spi,
FAR struct memlcd_priv_s *priv,
unsigned int devno);
#undef EXTERN
#ifdef __cplusplus
}
#endif
#endif /* __INCLUDE_NUTTX_MEMLCD_H */