12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223 |
- /****************************************************************************
- * drivers/lcd/ili9341.c
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership. The
- * ASF licenses this file to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance with the
- * License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- *
- ****************************************************************************/
- /* References: ILI9341_DS_V1.10.pdf (Rev: 1.10), "a-Si TFT LCD Single Chip
- * Driver 240RGBx320 Resolution and 262K color",
- * ILI TECHNOLOGY CORP., http://www.ilitek.com.
- */
- /****************************************************************************
- * Included Files
- ****************************************************************************/
- #include <nuttx/config.h>
- #include <sys/types.h>
- #include <stdint.h>
- #include <stdbool.h>
- #include <string.h>
- #include <assert.h>
- #include <errno.h>
- #include <debug.h>
- #include <nuttx/arch.h>
- #include <nuttx/lcd/lcd.h>
- #include <nuttx/lcd/ili9341.h>
- #include <arch/irq.h>
- /****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
- /* This is the generic lcd driver interface for the ili9341 Single Chip LCD
- * driver. The driver supports multiple displays, each connected with an own
- * ili9341 Single Chip LCD driver. The communication with the LCD single chip
- * driver must be provide by a subdriver accessible through the ili9341_dev_s
- * structure which is platform and MCU interface specific.
- *
- * Supported MCU interfaces (planned to support)
- *
- * Interface I
- *
- * 8080 MCU 8-bit bus interface
- * 8080 MCU 16-bit bus interface
- * 8080 MCU 9-bit bus interface
- * 8080 MCU 18-bit bus interface
- * 3-wire 9-bit data serial interface
- * 4-wire 8-bit data serial interface
- *
- * Interface II
- *
- * 8080 MCU 8-bit bus interface
- * 8080 MCU 16-bit bus interface
- * 8080 MCU 9-bit bus interface
- * 8080 MCU 18-bit bus interface
- * 3-wire 9-bit data serial Interface
- * 4-wire 8-bit data serial Interface
- *
- * Note! RGB interface will not supported by the lcd driver.
- * It should be use with the platform specific RGB graphic controller and the
- * nuttx framebuffer interface.
- *
- */
- /* Fundamental command and parameter definition */
- /* Interface control (IFCTL)
- *
- *
- * Parameter 1: 0x0001
- *
- * MY_EOR: 0
- * MX_EOR: 0
- * MV_EOR: 0
- * BGR_EOR: 0
- * WEMODE: 1 Reset column and page if data transfer exceeds
- */
- #define ILI9341_IFCTL_MYEOR 0
- #define ILI9341_IFCTL_MXEOR 0
- #define ILI9341_IFCTL_MVEOR 0
- #define ILI9341_IFCTL_BGREOR 0
- #define ILI9341_IFCTL_WEMODE ILI9341_INTERFACE_CONTROL_WEMODE
- #define ILI9341_IFCTL_PARAM1 ILI9341_IFCTL_MYEOR | ILI9341_IFCTL_MXEOR | \
- ILI9341_IFCTL_MVEOR | ILI9341_IFCTL_BGREOR | \
- ILI9341_IFCTL_WEMODE
- /* Parameter 2: 0x0000
- *
- * EPF: 0 65k color format for RGB interface, not used set to default
- * MDT: 0 Display data transfer mode, not used
- *
- * Note!
- * If RGB666 and 16-bit 8080-I interface supported by the driver, MDT must
- * be defined for each selected driver instance. Leave it empty for now.
- */
- #define ILI9341_IFCTL_EPF ILI9341_INTERFACE_CONTROL_EPF(0)
- #define ILI9341_IFCTL_MDT ILI9341_INTERFACE_CONTROL_MDT(0)
- #define ILI9341_IFCTL_PARAM2 ILI9341_IFCTL_EPF | ILI9341_IFCTL_MDT
- /* Parameter 3: 0x0000/0x0020
- *
- * ENDIAN: 0/1 Depending on endian mode of the mcu?
- * DM: 0 Internal clock operation
- * RM: 0 System interface/VSYNC interface
- * RIM: 0 RGB interface mode, unimportant set to default
- *
- */
- #ifdef CONFIG_ENDIAN_BIG
- # define ILI9341_IFCTL_ENDIAN 0
- #else
- # define ILI9341_IFCTL_ENDIAN ILI9341_INTERFACE_CONTROL_ENDIAN
- #endif
- #define ILI9341_IFCTL_DM ILI9341_INTERFACE_CONTROL_DM(0)
- #define ILI9341_IFCTL_RM 0
- #define ILI9341_IFCTL_RIM 0
- #define ILI9341_IFCTL_PARAM3 ILI9341_IFCTL_RIM | ILI9341_IFCTL_RM | \
- ILI9341_IFCTL_DM | ILI9341_IFCTL_ENDIAN
- /* Memory access control (MADCTL) */
- /* Landscape: 00100000 / 00101000 / h28
- *
- * MY: 0
- * MX: 0
- * MV: 1
- * ML: 0
- * BGR: 0/1 Depending on endian mode of the mcu?
- * MH: 0
- */
- #define ILI9341_MADCTL_LANDSCAPE_MY 0
- #define ILI9341_MADCTL_LANDSCAPE_MX 0
- #define ILI9341_MADCTL_LANDSCAPE_MV ILI9341_MEMORY_ACCESS_CONTROL_MV
- #define ILI9341_MADCTL_LANDSCAPE_ML 0
- #ifdef CONFIG_ENDIAN_BIG
- # define ILI9341_MADCTL_LANDSCAPE_BGR 0
- #else
- # define ILI9341_MADCTL_LANDSCAPE_BGR ILI9341_MEMORY_ACCESS_CONTROL_BGR
- #endif
- #define ILI9341_MADCTL_LANDSCAPE_MH 0
- #define ILI9341_MADCTL_LANDSCAPE_PARAM1 (ILI9341_MADCTL_LANDSCAPE_MY | \
- ILI9341_MADCTL_LANDSCAPE_MX | \
- ILI9341_MADCTL_LANDSCAPE_MV | \
- ILI9341_MADCTL_LANDSCAPE_ML | \
- ILI9341_MADCTL_LANDSCAPE_BGR | \
- ILI9341_MADCTL_LANDSCAPE_MH)
- /* Portrait: 00000000 / 00001000 / h08
- *
- * MY: 0
- * MX: 0
- * MV: 0
- * ML: 0
- * BGR: 0/1 Depending on endian mode of the mcu?
- * MH: 0
- */
- #define ILI9341_MADCTL_PORTRAIT_MY 0
- #define ILI9341_MADCTL_PORTRAIT_MX ILI9341_MEMORY_ACCESS_CONTROL_MX
- #define ILI9341_MADCTL_PORTRAIT_MV 0
- #define ILI9341_MADCTL_PORTRAIT_ML ILI9341_MEMORY_ACCESS_CONTROL_ML
- #ifdef CONFIG_ENDIAN_BIG
- # define ILI9341_MADCTL_PORTRAIT_BGR 0
- #else
- # define ILI9341_MADCTL_PORTRAIT_BGR ILI9341_MEMORY_ACCESS_CONTROL_BGR
- #endif
- #define ILI9341_MADCTL_PORTRAIT_MH 0
- #define ILI9341_MADCTL_PORTRAIT_PARAM1 (ILI9341_MADCTL_PORTRAIT_MY | \
- ILI9341_MADCTL_PORTRAIT_MX | \
- ILI9341_MADCTL_PORTRAIT_MV | \
- ILI9341_MADCTL_PORTRAIT_ML | \
- ILI9341_MADCTL_PORTRAIT_BGR | \
- ILI9341_MADCTL_PORTRAIT_MH)
- /* RLandscape: 01100000 / 01101000 / h68
- *
- * MY: 0
- * MX: 1
- * MV: 1
- * ML: 0
- * BGR: 0/1 Depending on endian mode of the mcu?
- * MH: 0
- */
- #define ILI9341_MADCTL_RLANDSCAPE_MY ILI9341_MEMORY_ACCESS_CONTROL_MY
- #define ILI9341_MADCTL_RLANDSCAPE_MX ILI9341_MEMORY_ACCESS_CONTROL_MX
- #define ILI9341_MADCTL_RLANDSCAPE_MV ILI9341_MEMORY_ACCESS_CONTROL_MV
- #define ILI9341_MADCTL_RLANDSCAPE_ML 0
- #ifdef CONFIG_ENDIAN_BIG
- # define ILI9341_MADCTL_RLANDSCAPE_BGR 0
- #else
- # define ILI9341_MADCTL_RLANDSCAPE_BGR ILI9341_MEMORY_ACCESS_CONTROL_BGR
- #endif
- #define ILI9341_MADCTL_RLANDSCAPE_MH 0
- #define ILI9341_MADCTL_RLANDSCAPE_PARAM1 \
- (ILI9341_MADCTL_RLANDSCAPE_MY | \
- ILI9341_MADCTL_RLANDSCAPE_MX | \
- ILI9341_MADCTL_RLANDSCAPE_MV | \
- ILI9341_MADCTL_RLANDSCAPE_ML | \
- ILI9341_MADCTL_RLANDSCAPE_BGR | \
- ILI9341_MADCTL_RLANDSCAPE_MH)
- /* RPortrait: 11000000 / 11001000 / hc8
- *
- * MY: 1
- * MX: 1
- * MV: 0
- * ML: 0
- * BGR: 0/1 Depending on endian mode of the mcu?
- * MH: 0
- *
- */
- #define ILI9341_MADCTL_RPORTRAIT_MY ILI9341_MEMORY_ACCESS_CONTROL_MY
- #define ILI9341_MADCTL_RPORTRAIT_MX 0
- #define ILI9341_MADCTL_RPORTRAIT_MV 0
- #define ILI9341_MADCTL_RPORTRAIT_ML ILI9341_MEMORY_ACCESS_CONTROL_ML
- #ifdef CONFIG_ENDIAN_BIG
- # define ILI9341_MADCTL_RPORTRAIT_BGR 0
- #else
- # define ILI9341_MADCTL_RPORTRAIT_BGR ILI9341_MEMORY_ACCESS_CONTROL_BGR
- #endif
- #define ILI9341_MADCTL_RPORTRAIT_MH 0
- #define ILI9341_MADCTL_RPORTRAIT_PARAM1 (ILI9341_MADCTL_RPORTRAIT_MY | \
- ILI9341_MADCTL_RPORTRAIT_MX | \
- ILI9341_MADCTL_RPORTRAIT_MV | \
- ILI9341_MADCTL_RPORTRAIT_ML | \
- ILI9341_MADCTL_RPORTRAIT_BGR | \
- ILI9341_MADCTL_RPORTRAIT_MH)
- /* Pixel Format Set (COLMOD)
- *
- * Note! RGB interface settings (DPI) is unimportant for the MCU interface
- * mode but set the register to the defined state equal to the MCU interface
- * pixel format.
- *
- * 16 Bit MCU: 01010101 / h55
- *
- * DPI: 5 (RGB16-565 RGB interface, not used)
- * DBI: 5 (RGB16-565 MCU interface
- */
- #define ILI9341_PIXSET_16BITDPI ILI9341_PIXEL_FORMAT_SET_DPI(5)
- #define ILI9341_PIXSET_16BITDBI ILI9341_PIXEL_FORMAT_SET_DBI(5)
- #define ILI9341_PIXSET_16BITMCU_PARAM1 (ILI9341_PIXSET_16BITDPI | \
- ILI9341_PIXSET_16BITDBI)
- /* 18-bit MCU: 01100110 / h66 (not supported by nuttx until now)
- *
- * DPI: 6 (RGB18-666 RGB interface)
- * DBI: 6 (RGB18-666 MCU interface)
- */
- #define ILI9341_PIXSET_18BITDPI ILI9341_PIXEL_FORMAT_SET_DPI(6)
- #define ILI9341_PIXSET_18BITDBI ILI9341_PIXEL_FORMAT_SET_DBI(6)
- #define ILI9341_PIXSET_18BITMCU_PARAM1 (ILI9341_PIXSET_18BITDPI | \
- ILI9341_PIXSET_18BITDBI)
- /* General fix display resolution */
- #define ILI9341_XRES 240
- #define ILI9341_YRES 320
- /* Validate configuration */
- #if CONFIG_LCD_ILI9341_NINTERFACES < 1
- # undef CONFIG_LCD_ILI9341_IFACE0
- #elif CONFIG_LCD_ILI9341_NINTERFACES < 2
- # undef CONFIG_LCD_ILI9341_IFACE1
- #endif
- /* First LCD display */
- #ifdef CONFIG_LCD_ILI9341_IFACE0
- # if defined(CONFIG_LCD_ILI9341_IFACE0_LANDSCAPE)
- # define ILI9341_IFACE0_ORIENT ILI9341_MADCTL_LANDSCAPE_PARAM1
- # define ILI9341_IFACE0_STRIDE ILI9341_YRES
- # elif defined(CONFIG_LCD_ILI9341_IFACE0_PORTRAIT)
- # define ILI9341_IFACE0_ORIENT ILI9341_MADCTL_PORTRAIT_PARAM1
- # define ILI9341_IFACE0_STRIDE ILI9341_XRES
- # elif defined(CONFIG_LCD_ILI9341_IFACE0_RLANDSCAPE)
- # define ILI9341_IFACE0_ORIENT ILI9341_MADCTL_RLANDSCAPE_PARAM1
- # define ILI9341_IFACE0_STRIDE ILI9341_YRES
- # elif defined(CONFIG_LCD_ILI9341_IFACE0_RPORTRAIT)
- # define ILI9341_IFACE0_ORIENT ILI9341_MADCTL_RPORTRAIT_PARAM1
- # define ILI9341_IFACE0_STRIDE ILI9341_XRES
- # endif
- # ifdef CONFIG_LCD_ILI9341_IFACE0_RGB565
- # define ILI9341_IFACE0_PXFMT FB_FMT_RGB16_565
- # define ILI9341_IFACE0_BPP 16
- # define ILI9341_IFACE0_BUFFER ILI9341_IFACE0_STRIDE
- # else
- # error "undefined pixel format for lcd interface 0"
- # endif
- #endif
- /* Second LCD display */
- #ifdef CONFIG_LCD_ILI9341_IFACE1
- # ifdef CONFIG_LCD_ILI9341_IFACE1_LANDSCAPE
- # define ILI9341_IFACE1_ORIENT ILI9341_MADCTL_LANDSCAPE_PARAM1
- # define ILI9341_IFACE1_STRIDE ILI9341_YRES
- # elif CONFIG_LCD_ILI9341_IFACE1_PORTRAIT
- # define ILI9341_IFACE1_ORIENT ILI9341_MADCTL_PORTRAIT_PARAM1
- # define ILI9341_IFACE1_STRIDE ILI9341_XRES
- # elif CONFIG_LCD_ILI9341_IFACE1_RLANDSCAPE
- # define ILI9341_IFACE1_ORIENT ILI9341_MADCTL_RLANDSCAPE_PARAM1
- # define ILI9341_IFACE1_STRIDE ILI9341_YRES
- # elif CONFIG_LCD_ILI9341_IFACE1_RPORTRAIT
- # define ILI9341_IFACE1_ORIENT ILI9341_MADCTL_RPORTRAIT_PARAM1
- # define ILI9341_IFACE1_STRIDE ILI9341_XRES
- # endif
- # ifdef CONFIG_LCD_ILI9341_IFACE1_RGB565
- # define ILI9341_IFACE1_PXFMT FB_FMT_RGB16_565
- # define ILI9341_IFACE1_BPP 16
- # define ILI9341_IFACE1_BUFFER ILI9341_IFACE1_STRIDE
- # else
- # error "undefined pixel format for lcd interface 1"
- # endif
- #endif
- /****************************************************************************
- * Private Type Definition
- ****************************************************************************/
- /* Each single connected ili9341 LCD driver needs an own driver instance
- * to provide a unique getrun and putrun method. Also store fundamental
- * parameter in driver internal structure. This minimal overhead should be
- * acceptable.
- */
- struct ili9341_dev_s
- {
- /* Publicly visible device structure */
- struct lcd_dev_s dev;
- /* Private driver-specific information follows */
- FAR struct ili9341_lcd_s *lcd;
- /* Driver specific putrun function */
- int (*putrun)(fb_coord_t row, fb_coord_t col,
- FAR const uint8_t * buffer, size_t npixels);
- #ifndef CONFIG_LCD_NOGETRUN
- /* Driver specific getrun function */
- int (*getrun)(fb_coord_t row, fb_coord_t col,
- FAR uint8_t * buffer, size_t npixels);
- #endif
- /* Run buffer for the device */
- uint16_t *runbuffer;
- /* Display orientation, e.g. Landscape, Portrait */
- uint8_t orient;
- /* LCD driver pixel format */
- uint8_t pxfmt;
- /* LCD driver color depth */
- uint8_t bpp;
- /* Current power state of the device */
- uint8_t power;
- };
- /****************************************************************************
- * Private Function Protototypes
- ****************************************************************************/
- /* Internal low level helpers */
- static inline uint16_t ili9341_getxres(FAR struct ili9341_dev_s *dev);
- static inline uint16_t ili9341_getyres(FAR struct ili9341_dev_s *dev);
- /* lcd data transfer methods */
- static int ili9341_putrun(int devno, fb_coord_t row, fb_coord_t col,
- FAR const uint8_t * buffer, size_t npixels);
- #ifndef CONFIG_LCD_NOGETRUN
- static int ili9341_getrun(int devno, fb_coord_t row, fb_coord_t col,
- FAR uint8_t * buffer, size_t npixels);
- #endif
- /* Definition of the public visible getrun / putrun methods
- * each for a single LCD driver
- */
- #ifdef CONFIG_LCD_ILI9341_IFACE0
- static int ili9341_putrun0(fb_coord_t row, fb_coord_t col,
- FAR const uint8_t *buffer, size_t npixsels);
- #endif
- #ifdef CONFIG_LCD_ILI9341_IFACE1
- static int ili9341_putrun1(fb_coord_t row, fb_coord_t col,
- FAR const uint8_t * buffer, size_t npixsels);
- #endif
- #ifndef CONFIG_LCD_NOGETRUN
- # ifdef CONFIG_LCD_ILI9341_IFACE0
- static int ili9341_getrun0(fb_coord_t row, fb_coord_t col,
- FAR uint8_t * buffer, size_t npixsels);
- # endif
- # ifdef CONFIG_LCD_ILI9341_IFACE1
- static int ili9341_getrun1(fb_coord_t row, fb_coord_t col,
- FAR uint8_t * buffer, size_t npixsels);
- # endif
- #endif
- /* lcd configuration */
- static int ili9341_getvideoinfo(FAR struct lcd_dev_s *dev,
- FAR struct fb_videoinfo_s *vinfo);
- static int ili9341_getplaneinfo(FAR struct lcd_dev_s *dev,
- unsigned int planeno,
- FAR struct lcd_planeinfo_s *pinfo);
- /* lcd specific controls */
- static int ili9341_getpower(struct lcd_dev_s *dev);
- static int ili9341_setpower(struct lcd_dev_s *dev, int power);
- static int ili9341_getcontrast(struct lcd_dev_s *dev);
- static int ili9341_setcontrast(struct lcd_dev_s *dev, unsigned int contrast);
- /****************************************************************************
- * Private Data
- ****************************************************************************/
- /* Initialize driver instance 1 < LCD_ILI9341_NINTERFACES */
- #ifdef CONFIG_LCD_ILI9341_IFACE0
- static uint16_t g_runbuffer0[ILI9341_IFACE0_BUFFER];
- #endif
- #ifdef CONFIG_LCD_ILI9341_IFACE1
- static uint16_t g_runbuffer1[ILI9341_IFACE1_BUFFER];
- #endif
- static struct ili9341_dev_s g_lcddev[CONFIG_LCD_ILI9341_NINTERFACES] =
- {
- #ifdef CONFIG_LCD_ILI9341_IFACE0
- {
- .lcd = 0,
- .putrun = ili9341_putrun0,
- # ifndef CONFIG_LCD_NOGETRUN
- .getrun = ili9341_getrun0,
- # endif
- .runbuffer = g_runbuffer0,
- .orient = ILI9341_IFACE0_ORIENT,
- .pxfmt = ILI9341_IFACE0_PXFMT,
- .bpp = ILI9341_IFACE0_BPP,
- .power = 0,
- },
- #endif
- #ifdef CONFIG_LCD_ILI9341_IFACE1
- {
- .lcd = 0,
- .putrun = ili9341_putrun1,
- # ifndef CONFIG_LCD_NOGETRUN
- .getrun = ili9341_getrun1,
- # endif
- .runbuffer = g_runbuffer1,
- .orient = ILI9341_IFACE1_ORIENT,
- .pxfmt = ILI9341_IFACE1_PXFMT,
- .bpp = ILI9341_IFACE1_BPP,
- .power = 0,
- },
- #endif
- };
- /****************************************************************************
- * Private Functions
- ****************************************************************************/
- /****************************************************************************
- * Name: ili9341_getxres
- *
- * Description:
- * Get horizontal resolution of the connected LCD driver depending on the
- * configured display orientation.
- *
- * Input Parameters:
- * dev - Reference to private driver structure
- *
- * Returned Value:
- *
- * Horizontal resolution
- *
- ****************************************************************************/
- static inline uint16_t ili9341_getxres(FAR struct ili9341_dev_s *dev)
- {
- if (dev->orient == ILI9341_MADCTL_LANDSCAPE_PARAM1 ||
- dev->orient == ILI9341_MADCTL_RLANDSCAPE_PARAM1)
- {
- return ILI9341_YRES;
- }
- return ILI9341_XRES;
- }
- /****************************************************************************
- * Name: ili9341_getyres
- *
- * Description:
- * Get vertical resolution of the connected LCD driver depending on the
- * configured display orientation.
- *
- * Input Parameters:
- * dev - Reference to private driver structure
- *
- * Returned Value:
- *
- * Vertical resolution
- *
- ****************************************************************************/
- static inline uint16_t ili9341_getyres(FAR struct ili9341_dev_s *dev)
- {
- if (dev->orient == ILI9341_MADCTL_LANDSCAPE_PARAM1 ||
- dev->orient == ILI9341_MADCTL_RLANDSCAPE_PARAM1)
- {
- return ILI9341_XRES;
- }
- return ILI9341_YRES;
- }
- /****************************************************************************
- * Name: ili9341_selectarea
- *
- * Description:
- * Select the active area for displaying pixel
- *
- * Input Parameters:
- * lcd - Reference to private driver structure
- * x0 - Start x position
- * y0 - Start y position
- * x1 - End x position
- * y1 - End y position
- *
- ****************************************************************************/
- static void ili9341_selectarea(FAR struct ili9341_lcd_s *lcd,
- uint16_t x0, uint16_t y0,
- uint16_t x1, uint16_t y1)
- {
- /* Select column */
- lcd->sendcmd(lcd, ILI9341_COLUMN_ADDRESS_SET);
- lcd->sendparam(lcd, (x0 >> 8));
- lcd->sendparam(lcd, (x0 & 0xff));
- lcd->sendparam(lcd, (x1 >> 8));
- lcd->sendparam(lcd, (x1 & 0xff));
- /* Select page */
- lcd->sendcmd(lcd, ILI9341_PAGE_ADDRESS_SET);
- lcd->sendparam(lcd, (y0 >> 8));
- lcd->sendparam(lcd, (y0 & 0xff));
- lcd->sendparam(lcd, (y1 >> 8));
- lcd->sendparam(lcd, (y1 & 0xff));
- }
- /****************************************************************************
- * Name: ili9341_putrun
- *
- * Description:
- * Write a partial raster line to the LCD.
- *
- * Input Parameters:
- * devno - Number of lcd device
- * 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
- * (range: 0 < npixels <= xres-col)
- *
- * Returned Value:
- *
- * On success - OK
- * On error - -EINVAL
- *
- ****************************************************************************/
- static int ili9341_putrun(int devno, fb_coord_t row, fb_coord_t col,
- FAR const uint8_t * buffer, size_t npixels)
- {
- FAR struct ili9341_dev_s *dev = &g_lcddev[devno];
- FAR struct ili9341_lcd_s *lcd = dev->lcd;
- FAR const uint16_t *src = (FAR const uint16_t *)buffer;
- DEBUGASSERT(buffer && ((uintptr_t)buffer & 1) == 0);
- /* Check if position outside of area */
- if (col + npixels > ili9341_getxres(dev) || row > ili9341_getyres(dev))
- {
- return -EINVAL;
- }
- /* Select lcd driver */
- lcd->select(lcd);
- /* Select column and area similar to the partial raster line */
- ili9341_selectarea(lcd, col, row, col + npixels - 1, row);
- /* Send memory write cmd */
- lcd->sendcmd(lcd, ILI9341_MEMORY_WRITE);
- /* Send pixel to gram */
- lcd->sendgram(lcd, src, npixels);
- /* Deselect the lcd driver */
- lcd->deselect(lcd);
- return OK;
- }
- /****************************************************************************
- * Name: ili9341_getrun
- *
- * Description:
- * Read a partial raster line from the LCD.
- *
- * Input Parameters:
- * devno - Number of the lcd device
- * 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)
- *
- * Returned Value:
- *
- * On success - OK
- * On error - -EINVAL
- *
- ****************************************************************************/
- # ifndef CONFIG_LCD_NOGETRUN
- static int ili9341_getrun(int devno, fb_coord_t row, fb_coord_t col,
- FAR uint8_t * buffer, size_t npixels)
- {
- FAR struct ili9341_dev_s *dev = &g_lcddev[devno];
- FAR struct ili9341_lcd_s *lcd = dev->lcd;
- FAR uint16_t *dest = (FAR uint16_t *)buffer;
- DEBUGASSERT(buffer && ((uintptr_t)buffer & 1) == 0);
- /* Check if position outside of area */
- if (col + npixels > ili9341_getxres(dev) || row > ili9341_getyres(dev))
- {
- return -EINVAL;
- }
- /* Select lcd driver */
- lcd->select(lcd);
- /* Select column and area similar to the partial raster line */
- ili9341_selectarea(lcd, col, row, col + npixels - 1, row);
- /* Send memory read cmd */
- lcd->sendcmd(lcd, ILI9341_MEMORY_READ);
- /* Receive pixel to gram */
- lcd->recvgram(lcd, dest, npixels);
- /* Deselect the lcd driver */
- lcd->deselect(lcd);
- return OK;
- }
- #endif
- /****************************************************************************
- * Name: ili9341_hwinitialize
- *
- * Description:
- * Initialize and configure the ILI9341 LCD driver hardware.
- *
- * Input Parameters:
- * dev - A reference to the driver specific structure
- *
- * Returned Value:
- *
- * On success - OK
- * On error - EINVAL
- *
- ****************************************************************************/
- static int ili9341_hwinitialize(FAR struct ili9341_dev_s *dev)
- {
- #ifdef CONFIG_DEBUG_LCD_INFO
- uint8_t param;
- #endif
- FAR struct ili9341_lcd_s *lcd = dev->lcd;
- /* Select spi device */
- lcdinfo("Initialize lcd driver\n");
- lcd->select(lcd);
- #ifdef CONFIG_DEBUG_LCD_INFO
- /* Read display identification */
- lcd->sendcmd(lcd, ILI9341_READ_ID1);
- lcd->recvparam(lcd, ¶m);
- lcdinfo("ili9341 LCD driver: LCD modules manufacturer ID: %d\n", param);
- lcd->sendcmd(lcd, ILI9341_READ_ID2);
- lcd->recvparam(lcd, ¶m);
- lcdinfo("ili9341 LCD driver: LCD modules driver version ID: %d\n", param);
- lcd->sendcmd(lcd, ILI9341_READ_ID3);
- lcd->recvparam(lcd, ¶m);
- lcdinfo("ili9341 LCD driver: LCD modules driver ID: %d\n", param);
- #endif
- /* Reset the lcd display to the default state */
- lcdinfo("ili9341 LCD driver: Software Reset\n");
- lcd->sendcmd(lcd, ILI9341_SOFTWARE_RESET);
- up_mdelay(5);
- lcdinfo("ili9341 LCD driver: set Memory Access Control: %04x\n",
- dev->orient);
- lcd->sendcmd(lcd, ILI9341_MEMORY_ACCESS_CONTROL);
- lcd->sendparam(lcd, dev->orient);
- /* Select column and area */
- ili9341_selectarea(lcd, 0, 0, ILI9341_XRES, ILI9341_YRES);
- /* Pixel Format set */
- lcd->sendcmd(lcd, ILI9341_PIXEL_FORMAT_SET);
- /* 16 bit RGB565 */
- lcdinfo("ili9341 LCD driver: Set Pixel Format: %04x\n",
- ILI9341_PIXSET_16BITMCU_PARAM1);
- lcd->sendparam(lcd, ILI9341_PIXSET_16BITMCU_PARAM1);
- /* 18 bit RGB666, add settings here */
- lcdinfo("ili9341 LCD driver: Set Interface control\n");
- lcd->sendcmd(lcd, ILI9341_INTERFACE_CONTROL);
- lcd->sendparam(lcd, ILI9341_IFCTL_PARAM1);
- lcd->sendparam(lcd, ILI9341_IFCTL_PARAM2);
- lcd->sendparam(lcd, ILI9341_IFCTL_PARAM3);
- /* Sleep out */
- lcdinfo("ili9341 LCD driver: Sleep Out\n");
- lcd->sendcmd(lcd, ILI9341_SLEEP_OUT);
- up_mdelay(120);
- /* Deselect the device */
- lcd->deselect(lcd);
- /* Switch display off */
- ili9341_setpower(&dev->dev, 0);
- return OK;
- }
- /****************************************************************************
- * Public Functions
- ****************************************************************************/
- /****************************************************************************
- * Name: ili9341_putrunx
- *
- * Description:
- * Write a partial raster line to the LCD.
- *
- * Input Parameters:
- * row - Starting row to write to (range: 0 <= row < yres)
- * col - Starting column to write to (range: 0 <= col <= xres-npixels)
- * buffer - The buffer containing the run to be written to the LCD
- * npixels - The number of pixels to write to the
- * (range: 0 < npixels <= xres-col)
- *
- * Returned Value:
- *
- * On success - OK
- * On error - -EINVAL
- *
- ****************************************************************************/
- #ifdef CONFIG_LCD_ILI9341_IFACE0
- static int ili9341_putrun0(fb_coord_t row, fb_coord_t col,
- FAR const uint8_t * buffer, size_t npixels)
- {
- return ili9341_putrun(0, row, col, buffer, npixels);
- }
- #endif
- #ifdef CONFIG_LCD_ILI9341_IFACE1
- static int ili9341_putrun1(fb_coord_t row, fb_coord_t col,
- FAR const uint8_t * buffer, size_t npixels)
- {
- return ili9341_putrun(1, row, col, buffer, npixels);
- }
- #endif
- /****************************************************************************
- * Name: ili9341_getrunx
- *
- * Description:
- * Read a partial raster line from the LCD.
- *
- * Input Parameters:
- * row - Starting row to read from (range: 0 <= row < yres)
- * col - Starting column to read from (range: 0 <= col <= xres-npixels)
- * buffer - The buffer containing the run to be written to the LCD
- * npixels - The number of pixels to read from the
- * (range: 0 < npixels <= xres-col)
- *
- * Returned Value:
- *
- * On success - OK
- * On error - -EINVAL
- *
- ****************************************************************************/
- #ifndef CONFIG_LCD_NOGETRUN
- # ifdef CONFIG_LCD_ILI9341_IFACE0
- static int ili9341_getrun0(fb_coord_t row, fb_coord_t col,
- FAR uint8_t * buffer, size_t npixels)
- {
- return ili9341_getrun(0, row, col, buffer, npixels);
- }
- # endif
- # ifdef CONFIG_LCD_ILI9341_IFACE1
- static int ili9341_getrun1(fb_coord_t row, fb_coord_t col,
- FAR uint8_t * buffer, size_t npixels)
- {
- return ili9341_getrun(1, row, col, buffer, npixels);
- }
- # endif
- #endif
- /****************************************************************************
- * Name: ili9341_getvideoinfo
- *
- * Description:
- * Get information about the LCD video controller configuration.
- *
- * Input Parameters:
- * dev - A reference to the driver specific structure
- * vinfo - A reference to the videoinfo structure
- *
- * Returned Value:
- *
- * On success - OK
- * On error - -EINVAL
- *
- ****************************************************************************/
- static int ili9341_getvideoinfo(FAR struct lcd_dev_s *dev,
- FAR struct fb_videoinfo_s *vinfo)
- {
- if (dev && vinfo)
- {
- FAR struct ili9341_dev_s *priv = (FAR struct ili9341_dev_s *)dev;
- vinfo->fmt = priv->pxfmt;
- vinfo->xres = ili9341_getxres(priv);
- vinfo->yres = ili9341_getyres(priv);
- vinfo->nplanes = 1;
- lcdinfo("fmt: %d xres: %d yres: %d nplanes: %d\n",
- vinfo->fmt, vinfo->xres, vinfo->yres, vinfo->nplanes);
- return OK;
- }
- return -EINVAL;
- }
- /****************************************************************************
- * Name: ili9341_getplaneinfo
- *
- * Description:
- * Get information about the configuration of each LCD color plane.
- *
- * Input Parameters:
- * dev - A reference to the driver specific structure
- * planeno - The plane number
- * pinfo - A reference to the planeinfo structure
- *
- * Returned Value:
- *
- * On success - OK
- * On error - -EINVAL
- *
- ****************************************************************************/
- static int ili9341_getplaneinfo(FAR struct lcd_dev_s *dev,
- unsigned int planeno,
- FAR struct lcd_planeinfo_s *pinfo)
- {
- if (dev && pinfo && planeno == 0)
- {
- FAR struct ili9341_dev_s *priv = (FAR struct ili9341_dev_s *)dev;
- pinfo->putrun = priv->putrun;
- #ifndef CONFIG_LCD_NOGETRUN
- pinfo->getrun = priv->getrun;
- #endif
- pinfo->bpp = priv->bpp;
- pinfo->buffer = (FAR uint8_t *)priv->runbuffer; /* Run scratch buffer */
- lcdinfo("planeno: %d bpp: %d\n", planeno, pinfo->bpp);
- return OK;
- }
- return -EINVAL;
- }
- /****************************************************************************
- * Name: ili9341_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.
- *
- * Input Parameters:
- * dev - A reference to the driver specific structure
- *
- * Returned Value:
- *
- * On success - OK
- * On error - -EINVAL
- *
- ****************************************************************************/
- static int ili9341_getpower(FAR struct lcd_dev_s *dev)
- {
- FAR struct ili9341_dev_s *priv = (FAR struct ili9341_dev_s *)dev;
- if (priv)
- {
- lcdinfo("%d\n", priv->power);
- return priv->power;
- }
- return -EINVAL;
- }
- /****************************************************************************
- * Name: ili9341_setpower
- *
- * Description:
- * Enable/disable LCD panel power
- * (0: full off - CONFIG_LCD_MAXPOWER: full on).
- * On backlight LCDs, this setting may correspond to the backlight setting.
- *
- * Input Parameters:
- * dev - A reference to the driver specific structure
- * power - Value of the power
- *
- * Returned Value:
- *
- * On success - OK
- * On error - -EINVAL
- *
- ****************************************************************************/
- static int ili9341_setpower(FAR struct lcd_dev_s *dev, int power)
- {
- FAR struct ili9341_dev_s *priv = (FAR struct ili9341_dev_s *)dev;
- FAR struct ili9341_lcd_s *lcd = priv->lcd;
- if (dev)
- {
- lcdinfo("%d\n", power);
- lcd->select(lcd);
- if (power > 0)
- {
- /* Set backlight level */
- lcd->backlight(lcd, power);
- /* And switch LCD on */
- lcd->sendcmd(lcd, ILI9341_DISPLAY_ON);
- up_mdelay(120);
- }
- else
- {
- /* Switch LCD off */
- lcd->sendcmd(lcd, ILI9341_DISPLAY_OFF);
- }
- lcd->deselect(lcd);
- priv->power = power;
- return OK;
- }
- return -EINVAL;
- }
- /****************************************************************************
- * Name: ili9341_getcontrast
- *
- * Description:
- * Get the current contrast setting (0-CONFIG_LCD_MAXCONTRAST).
- *
- * Input Parameters:
- * dev - A reference to the lcd driver structure
- *
- * Returned Value:
- *
- * On success - current contrast value
- * On error - -ENOSYS, not supported by the ili9341.
- *
- ****************************************************************************/
- static int ili9341_getcontrast(struct lcd_dev_s *dev)
- {
- lcdinfo("Not implemented\n");
- return -ENOSYS;
- }
- /****************************************************************************
- * Name: ili9341_setcontrast
- *
- * Description:
- * Set LCD panel contrast (0-CONFIG_LCD_MAXCONTRAST).
- *
- * Input Parameters:
- * dev - A reference to the lcd driver structure
- *
- * Returned Value:
- *
- * On success - OK
- * On error - -ENOSYS, not supported by the ili9341.
- *
- ****************************************************************************/
- static int ili9341_setcontrast(struct lcd_dev_s *dev, unsigned int contrast)
- {
- lcdinfo("contrast: %d\n", contrast);
- return -ENOSYS;
- }
- /****************************************************************************
- * Name: ili9341_initialize
- *
- * Description:
- * Initialize the LCD video driver internal structure. Also initialize the
- * lcd hardware if not done. The control of the LCD driver is depend on the
- * selected MCU interface and part of the platform specific subdriver (see
- * config/stm32f429i-disco/src/stm32_ili93414ws.c)
- *
- * Input Parameters:
- *
- * lcd - A reference to the platform specific driver instance to control
- * the ili9341 display driver.
- * devno - A value in the range of 0 through CONFIG_ILI9341_NINTERFACES-1.
- * This allows support for multiple LCD devices.
- *
- * Returned Value:
- *
- * On success, this function returns a reference to the LCD driver object
- * for the specified LCD driver. NULL is returned on any failure.
- *
- ****************************************************************************/
- FAR struct lcd_dev_s *
- ili9341_initialize(FAR struct ili9341_lcd_s *lcd, int devno)
- {
- if (lcd && devno >= 0 && devno < CONFIG_LCD_ILI9341_NINTERFACES)
- {
- FAR struct ili9341_dev_s *priv = &g_lcddev[devno];
- /* Check if initialized */
- if (!priv->lcd)
- {
- FAR struct lcd_dev_s *dev = &priv->dev;
- int ret;
- /* Initialize internal structure */
- dev->getvideoinfo = ili9341_getvideoinfo;
- dev->getplaneinfo = ili9341_getplaneinfo;
- dev->getpower = ili9341_getpower;
- dev->setpower = ili9341_setpower;
- dev->getcontrast = ili9341_getcontrast;
- dev->setcontrast = ili9341_setcontrast;
- priv->lcd = lcd;
- /* Initialize the LCD driver */
- ret = ili9341_hwinitialize(priv);
- if (ret == OK)
- {
- return &priv->dev;
- }
- }
- }
- return NULL;
- }
- /****************************************************************************
- * Name: ili9341_clear
- *
- * Description:
- * This is a non-standard LCD interface. 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.
- *
- * Input Parameters:
- * dev - A reference to the lcd driver structure
- * color - The background color
- *
- * Returned Value:
- *
- * On success - OK
- * On error - -EINVAL
- *
- ****************************************************************************/
- int ili9341_clear(FAR struct lcd_dev_s *dev, uint16_t color)
- {
- FAR struct ili9341_dev_s *priv = (FAR struct ili9341_dev_s *)dev;
- FAR struct ili9341_lcd_s *lcd = priv->lcd;
- uint16_t xres = ili9341_getxres(priv);
- uint16_t yres = ili9341_getyres(priv);
- uint32_t n;
- if (!lcd)
- {
- return -EINVAL;
- }
- /* Select lcd driver */
- lcd->select(lcd);
- /* Select column and area similar to the visible area */
- ili9341_selectarea(lcd, 0, 0, xres, yres);
- /* Send memory write cmd */
- lcd->sendcmd(lcd, ILI9341_MEMORY_WRITE);
- /* clear the visible area */
- for (n = 0; n < xres * yres; n++)
- {
- /* Send pixel to gram */
- lcd->sendgram(lcd, &color, 1);
- }
- /* Deselect the lcd driver */
- lcd->deselect(lcd);
- return OK;
- }
|