You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by "acassis (via GitHub)" <gi...@apache.org> on 2023/05/24 15:30:11 UTC

[GitHub] [nuttx] acassis commented on a diff in pull request #9372: drivers/lcd: Add JD9851 driver

acassis commented on code in PR #9372:
URL: https://github.com/apache/nuttx/pull/9372#discussion_r1204395223


##########
drivers/lcd/jd9851.c:
##########
@@ -0,0 +1,914 @@
+/****************************************************************************
+ * drivers/lcd/jd9851.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.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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/spi/spi.h>
+#include <nuttx/lcd/lcd.h>
+#include <nuttx/lcd/jd9851.h>
+
+#include "jd9851.h"
+
+#ifdef CONFIG_LCD_JD9851
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Verify that all configuration requirements have been met */
+
+#ifndef CONFIG_LCD_JD9851_SPIMODE
+#  define CONFIG_LCD_JD9851_SPIMODE SPIDEV_MODE0
+#endif
+
+/* SPI frequency */
+
+#ifndef CONFIG_LCD_JD9851_FREQUENCY
+#  define CONFIG_LCD_JD9851_FREQUENCY 1000000
+#endif
+
+/* Check contrast selection */
+
+#if !defined(CONFIG_LCD_MAXCONTRAST)
+#  define CONFIG_LCD_MAXCONTRAST 1
+#endif
+
+/* Check power setting */
+
+#if !defined(CONFIG_LCD_MAXPOWER) || CONFIG_LCD_MAXPOWER < 1
+#  define CONFIG_LCD_MAXPOWER 1
+#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
+
+/* Display Resolution */
+
+#if !defined(CONFIG_LCD_JD9851_XRES)
+#  define CONFIG_LCD_JD9851_XRES 240
+#endif
+
+#if !defined(CONFIG_LCD_JD9851_YRES)
+#  define CONFIG_LCD_JD9851_YRES 320
+#endif
+
+#if !defined(CONFIG_LCD_JD9851_BPP)
+#  define CONFIG_LCD_JD9851_BPP 16
+#endif
+
+#if !defined(CONFIG_LCD_JD9851_XOFFSET)
+#  define CONFIG_LCD_JD9851_XOFFSET 0
+#endif
+
+#if !defined(CONFIG_LCD_JD9851_YOFFSET)
+#  define CONFIG_LCD_JD9851_YOFFSET 0
+#endif
+
+#define JD9851_LUT_SIZE    CONFIG_LCD_JD9851_YRES
+
+#if defined(CONFIG_LCD_LANDSCAPE) || defined(CONFIG_LCD_RLANDSCAPE)
+#  define JD9851_XRES       CONFIG_LCD_JD9851_YRES
+#  define JD9851_YRES       CONFIG_LCD_JD9851_XRES
+#  define JD9851_XOFFSET    CONFIG_LCD_JD9851_YOFFSET
+#  define JD9851_YOFFSET    CONFIG_LCD_JD9851_XOFFSET
+#else
+#  define JD9851_XRES       CONFIG_LCD_JD9851_XRES
+#  define JD9851_YRES       CONFIG_LCD_JD9851_YRES
+#  define JD9851_XOFFSET    CONFIG_LCD_JD9851_XOFFSET
+#  define JD9851_YOFFSET    CONFIG_LCD_JD9851_YOFFSET
+#endif
+
+/* Color depth and format */
+
+#ifdef CONFIG_LCD_JD9851_BPP
+#  if (CONFIG_LCD_JD9851_BPP == 16)
+#    define JD9851_BPP           16
+#    define JD9851_COLORFMT      FB_FMT_RGB16_565
+#    define JD9851_BYTESPP       2
+#  else
+#    define JD9851_BPP           16
+#    define JD9851_COLORFMT      FB_FMT_RGB16_565
+#    define JD9851_BYTESPP       2
+#    warning "Invalid color depth.  Falling back to 16bpp"
+#  endif
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* This structure describes the state of this driver */
+
+struct jd9851_dev_s
+{
+  /* Publicly visible device structure */
+
+  struct lcd_dev_s dev;
+
+  /* Private LCD-specific information follows */
+
+  FAR struct spi_dev_s *spi;  /* SPI device */
+  uint8_t bpp;                /* Selected color depth */
+  uint8_t power;              /* Current power setting */
+
+  /* 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.
+   */
+
+  uint16_t runbuffer[JD9851_LUT_SIZE];
+};
+
+/****************************************************************************
+ * Private Function Protototypes
+ ****************************************************************************/
+
+/* Misc. Helpers */
+
+static void jd9851_select(FAR struct spi_dev_s *spi, int bits);
+static void jd9851_deselect(FAR struct spi_dev_s *spi);
+
+static inline void jd9851_sendcmd(FAR struct jd9851_dev_s *dev, uint8_t cmd);
+static void jd9851_cmddata(FAR struct jd9851_dev_s *dev, uint8_t cmd,
+                               const uint8_t *data, int len);
+static void jd9851_init(FAR struct jd9851_dev_s *dev);
+static void jd9851_sleep(FAR struct jd9851_dev_s *dev, bool sleep);
+static void jd9851_setorientation(FAR struct jd9851_dev_s *dev);
+static void jd9851_display(FAR struct jd9851_dev_s *dev, bool on);
+static void jd9851_setcursor(FAR struct jd9851_dev_s *dev,
+                           uint16_t x0, uint16_t y0,
+                           uint16_t x1, uint16_t y1);
+static void jd9851_bpp(FAR struct jd9851_dev_s *dev, int bpp);
+static void jd9851_wrram(FAR struct jd9851_dev_s *dev,
+                         FAR const uint8_t *buff, size_t size , size_t skip,
+                         size_t count);
+#ifndef CONFIG_LCD_NOGETRUN
+static void jd9851_rdram(FAR struct jd9851_dev_s *dev,
+                         FAR uint16_t *buff, size_t size);
+#endif
+static void jd9851_fill(FAR struct jd9851_dev_s *dev, uint16_t color);
+
+/* LCD Data Transfer Methods */
+
+static int jd9851_putrun(FAR struct lcd_dev_s *dev,
+                         fb_coord_t row, fb_coord_t col,
+                         FAR const uint8_t *buffer, size_t npixels);
+static int jd9851_putarea(FAR struct lcd_dev_s *dev,
+                          fb_coord_t row_start, fb_coord_t row_end,
+                          fb_coord_t col_start, fb_coord_t col_end,
+                          FAR const uint8_t *buffer, fb_coord_t stride);
+#ifndef CONFIG_LCD_NOGETRUN
+static int jd9851_getrun(FAR struct lcd_dev_s *dev,
+                         fb_coord_t row, fb_coord_t col,
+                         FAR uint8_t *buffer, size_t npixels);
+#endif
+
+/* LCD Configuration */
+
+static int jd9851_getvideoinfo(FAR struct lcd_dev_s *dev,
+                               FAR struct fb_videoinfo_s *vinfo);
+static int jd9851_getplaneinfo(FAR struct lcd_dev_s *dev,
+                               unsigned int planeno,
+                               FAR struct lcd_planeinfo_s *pinfo);
+
+/* LCD Specific Controls */
+
+static int jd9851_getpower(FAR struct lcd_dev_s *dev);
+static int jd9851_setpower(FAR struct lcd_dev_s *dev, int power);
+static int jd9851_getcontrast(FAR struct lcd_dev_s *dev);
+static int jd9851_setcontrast(FAR struct lcd_dev_s *dev,
+                              unsigned int contrast);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct jd9851_dev_s g_lcddev;
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: jd9851_select
+ *
+ * Description:
+ *   Select the SPI, locking and re-configuring if necessary
+ *
+ * Input Parameters:
+ *   spi   - Reference to the SPI driver structure
+ *   bits  - Number of SPI bits
+ *
+ * Returned Value:
+ *   None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+static void jd9851_select(FAR FAR struct spi_dev_s *spi, int bits)
+{
+  /* Select JD9851 chip (locking the SPI bus in case there are multiple
+   * devices competing for the SPI bus
+   */
+
+  SPI_LOCK(spi, true);
+  SPI_SELECT(spi, SPIDEV_DISPLAY(0), true);
+
+  /* Now make sure that the SPI bus is configured for the JD9851 (it
+   * might have gotten configured for a different device while unlocked)
+   */
+
+  SPI_SETMODE(spi, CONFIG_LCD_JD9851_SPIMODE);
+  SPI_SETBITS(spi, bits);
+  SPI_SETFREQUENCY(spi, CONFIG_LCD_JD9851_FREQUENCY);
+}
+
+/****************************************************************************
+ * Name: jd9851_deselect
+ *
+ * Description:
+ *   De-select the SPI
+ *
+ * Input Parameters:
+ *   spi  - Reference to the SPI driver structure
+ *
+ * Returned Value:
+ *   None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+static void jd9851_deselect(FAR FAR struct spi_dev_s *spi)
+{
+  /* De-select JD9851 chip and relinquish the SPI bus. */
+
+  SPI_SELECT(spi, SPIDEV_DISPLAY(0), false);
+  SPI_LOCK(spi, false);
+}
+
+/****************************************************************************
+ * Name: jd9851_sendcmd
+ *
+ * Description:
+ *   Send a command to the driver.
+ *
+ ****************************************************************************/
+
+static inline void jd9851_sendcmd(FAR struct jd9851_dev_s *dev, uint8_t cmd)
+{
+  jd9851_select(dev->spi, 8);
+  SPI_CMDDATA(dev->spi, SPIDEV_DISPLAY(0), true);
+  SPI_SEND(dev->spi, cmd);
+  SPI_CMDDATA(dev->spi, SPIDEV_DISPLAY(0), false);
+  jd9851_deselect(dev->spi);
+}
+
+/****************************************************************************
+ * Name: jd9851_cmddata
+ *
+ * Description:
+ *   Send a command and a series of data to the driver.
+ *
+ ****************************************************************************/
+
+static void jd9851_cmddata(FAR struct jd9851_dev_s *dev, uint8_t cmd,
+                                      const uint8_t *data, int len)
+{
+  jd9851_select(dev->spi, 8);
+  SPI_CMDDATA(dev->spi, SPIDEV_DISPLAY(0), true);
+  SPI_SEND(dev->spi, cmd);
+  SPI_CMDDATA(dev->spi, SPIDEV_DISPLAY(0), false);
+  SPI_SNDBLOCK(dev->spi, data, len);
+  jd9851_deselect(dev->spi);
+}
+
+/****************************************************************************
+ * Name: jd9851_init
+ *
+ * Description:
+ *   Send jd9851 internal init commands.
+ *
+ * Assumption/Limitations:
+ *   Initialization is hardware-specific and may need to be rewritten for
+ *   different modules.
+ *
+ ****************************************************************************/
+
+static void jd9851_init(FAR struct jd9851_dev_s *dev)
+{
+  jd9851_cmddata(dev, JD9851_PASSWORD, (const uint8_t *) "\x98\x51\xe9", 3);
+
+  jd9851_cmddata(dev, JD9851_SET_PAGE_CMD, (const uint8_t *) "\x00", 1);
+  jd9851_cmddata(dev, JD9851_GAMMA_SET_CMD, (const uint8_t *)
+                 "\x1b\x7a\x17\x32", 4);
+  jd9851_cmddata(dev, JD9851_R_GAMMA_SET_CMD, (const uint8_t *)
+                 "\x3c\x32\x2b\x2c\x2f\x32\x2c\x2b\x28\x27\x22\x16\x10\x0b\
+                  \x05\x0e\x3c\x32\x2b\x2c\x2f\x32\x2c\x2b\x28\x27\x22\x16\
+                  \x10\x0b\x05\x0e", 32);
+  jd9851_cmddata(dev, JD9851_POWER_CTRL, (const uint8_t *)
+                 "\x33\x28\xcc", 3);
+  jd9851_cmddata(dev, JD9851_DCDC_SET, (const uint8_t *)
+                 "\x47\x7a\x30\x30\x6c\x60\x50\x70", 8);
+  jd9851_cmddata(dev, JD9851_VDDD_CTRL, (const uint8_t *) "\x38\x3c", 2);
+  jd9851_cmddata(dev, JD9851_SETSTBA, (const uint8_t *) "\x31\x20", 2);
+  jd9851_cmddata(dev, JD9851_SETPANEL, (const uint8_t *) "\x16", 1);
+  jd9851_cmddata(dev, JD9851_SETRGBCYC, (const uint8_t *)
+                 "\x08\x00\x0a\x10\x08\x54\x45\x71\x2c", 9);
+  jd9851_cmddata(dev, JD9851_SETTCON, (const uint8_t *)
+                 "\x00\xa0\x79\x0e\x0a\x16\x79\x0e\x0a\x16\x79\x0e\x0a\x16\
+                  \x82\x00\x03", 17);
+  jd9851_cmddata(dev, JD9851_SETGD, (const uint8_t *)
+                 "\x04\x0c\x6b\x0f\x07\x03", 6);
+  jd9851_cmddata(dev, JD9851_SETRGBIF, (const uint8_t *) "\x22\x20", 2);
+  jd9851_cmddata(dev, JD9851_RAM_CTRL, (const uint8_t *) "\x00\x00", 2);
+
+  jd9851_cmddata(dev, JD9851_SET_PAGE_CMD, (const uint8_t *) "\x02", 1);
+  jd9851_cmddata(dev, JD9851_DCDC_SET2, (const uint8_t *)
+                 "\x19\xa0\x2f\x04\x33", 5);
+  jd9851_cmddata(dev, JD9851_SETPANEL, (const uint8_t *)
+                 "\x10\x66\x66\x01", 4);
+  jd9851_cmddata(dev, JD9851_OSCM_SET, (const uint8_t *) "\x01\x00\x00", 3);
+  jd9851_cmddata(dev, JD9851_SETMIPI_2, (const uint8_t *) "\x10\x20\xf4", 3);
+
+  jd9851_sendcmd(dev, JD9851_SLEEP_OUT);
+  up_mdelay(120);
+}
+
+/****************************************************************************
+ * Name: jd9851_sleep
+ *
+ * Description:
+ *   Sleep or wake up the driver.
+ *
+ ****************************************************************************/
+
+static void jd9851_sleep(FAR struct jd9851_dev_s *dev, bool sleep)
+{
+  if (sleep)
+    {
+      jd9851_sendcmd(dev, JD9851_SLEEP_IN);
+    }
+  else
+    {
+      jd9851_sendcmd(dev, JD9851_SLEEP_OUT);
+    }
+
+  up_mdelay(120);
+}
+
+/****************************************************************************
+ * Name: jd9851_display
+ *
+ * Description:
+ *   Turn on or off the display.
+ *
+ ****************************************************************************/
+
+static void jd9851_display(FAR struct jd9851_dev_s *dev, bool on)
+{
+  uint8_t reg;
+
+#if defined(CONFIG_LCD_JD9851_TE)
+  reg = JD9851_TE_MODE0;
+  jd9851_cmddata(dev, JD9851_TEON, &reg, 1);
+#endif
+
+#if defined(CONFIG_LCD_JD9851_INVERT)
+  jd9851_sendcmd(dev, JD9851_INVERSION_ON);
+#endif
+
+  if (on)
+    {
+      jd9851_sendcmd(dev, JD9851_DISON);
+    }
+  else
+    {
+      jd9851_sendcmd(dev, JD9851_DISOFF);
+    }
+}
+
+/****************************************************************************
+ * Name: jd9851_setorientation
+ *
+ * Description:
+ *   Set screen orientation.
+ *
+ ****************************************************************************/
+
+static void jd9851_setorientation(FAR struct jd9851_dev_s *dev)
+{
+  uint8_t reg = 0x00;
+
+#  if defined(CONFIG_LCD_RLANDSCAPE)
+
+  reg = JD9851_MADCTL_MY | JD9851_MADCTL_MV;
+
+#  elif defined(CONFIG_LCD_LANDSCAPE)
+
+  reg = JD9851_MADCTL_MV | JD9851_MADCTL_MX;
+
+#  elif defined(CONFIG_LCD_PORTRAIT)
+
+#  elif defined(CONFIG_LCD_RPORTRAIT)
+
+  reg = JD9851_MADCTL_MY | JD9851_MADCTL_MX;
+
+#  endif
+
+#  if defined(CONFIG_LCD_JD9851_BGR)
+
+  reg |= JD9851_MADCTL_BGR;
+
+#  endif

Review Comment:
   Please fix spacing after "#" on these #if / #elif / #endif



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org