You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2022/07/20 03:52:26 UTC

[incubator-nuttx] branch master updated: lcd/apa102: Add putarea() support for faster rendering

This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 9587e4a85e lcd/apa102: Add putarea() support for faster rendering
9587e4a85e is described below

commit 9587e4a85e46dd9214f208914134edb34f6cb0a2
Author: Alan Carvalho de Assis <ac...@gmail.com>
AuthorDate: Tue Jul 19 17:40:31 2022 -0300

    lcd/apa102: Add putarea() support for faster rendering
---
 drivers/lcd/apa102.c | 128 ++++++++++++++++++++++++++++++++++++---------------
 1 file changed, 90 insertions(+), 38 deletions(-)

diff --git a/drivers/lcd/apa102.c b/drivers/lcd/apa102.c
index dd21e63926..9e70895a4a 100644
--- a/drivers/lcd/apa102.c
+++ b/drivers/lcd/apa102.c
@@ -159,6 +159,10 @@ struct apa102_dev_s
 static int apa102_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 apa102_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);
 static int apa102_getrun(FAR struct lcd_dev_s *dev, fb_coord_t row,
                          fb_coord_t col, FAR uint8_t *buffer,
                          size_t npixels);
@@ -215,7 +219,7 @@ static const struct fb_videoinfo_s g_videoinfo =
 static const struct lcd_planeinfo_s g_planeinfo =
 {
   apa102_putrun,              /* Put a run into LCD memory */
-  NULL,                       /* No putarea function */
+  apa102_putarea,             /* Put a run into LCD memory */
   apa102_getrun,              /* Get a run from LCD memory */
   NULL,                       /* No getarea function */
   NULL,                       /* No redraw function */
@@ -347,6 +351,47 @@ static inline void apa102_write32(FAR struct apa102_dev_s *priv,
   SPI_LOCK(priv->spi, false);
 }
 
+/****************************************************************************
+ * Name: apa102_refresh
+ *
+ * Description:
+ *   Send converted framebuffer to the APA102 LED Matrix
+ *
+ ****************************************************************************/
+
+static inline void apa102_refresh(FAR struct apa102_dev_s *priv)
+{
+  int i;
+
+  /* Confirm that SPI is configured correctly */
+
+  apa102_configspi(priv->spi);
+
+  /* Send a start of frame */
+
+  apa102_write32(priv, APA102_START_FRAME);
+
+  /* Send all LEDs values in the matrix */
+
+  for (i = 0; i < (APA102_XRES * APA102_YRES); i++)
+    {
+      uint32_t *led = (uint32_t *) &priv->fb[i];
+
+      /* Then transfer 4 bytes per LED */
+
+      apa102_write32(priv, (uint32_t) (*led | APA102_HEADER_FRAME));
+    }
+
+  /* Send an end of frame */
+
+  apa102_write32(priv, APA102_END_FRAME);
+
+  for (i = 0; i < (1 + APA102_XRES * APA102_YRES / 32); i++)
+    {
+      apa102_write32(priv, 0);
+    }
+}
+
 /****************************************************************************
  * Name:  apa102_putrun
  *
@@ -401,34 +446,59 @@ static int apa102_putrun(FAR struct lcd_dev_s *dev, fb_coord_t row,
       priv->fb[(row * APA102_XRES) + col + i] = rgb565_apa102(*ptr++);
     }
 
-  /* Confirm that SPI is configured correctly */
+  /* Update the display with converted data */
 
-  apa102_configspi(priv->spi);
-
-  /* Send a start of frame */
-
-  apa102_write32(priv, APA102_START_FRAME);
+  apa102_refresh(priv);
 
-  /* Send all LEDs values in the matrix */
+  return OK;
+}
 
-  for (i = 0; i < (APA102_XRES * APA102_YRES); i++)
-    {
-      uint32_t *led = (uint32_t *) &priv->fb[i];
+/****************************************************************************
+ * Name:  apa102_putarea
+ *
+ * Description:
+ *   This method can be used to write a partial area to the LCD:
+ *
+ *   dev       - The lcd device
+ *   row_start - Starting row to write to (range: 0 <= row < yres)
+ *   row_end   - Ending row to write to (range: row_start <= row < yres)
+ *   col_start - Starting column to write to (range: 0 <= col <= xres)
+ *   col_end   - Ending column to write to
+ *               (range: col_start <= col_end < xres)
+ *   buffer    - The buffer containing the area to be written to the LCD
+ *
+ ****************************************************************************/
 
-      /* Then transfer 4 bytes per LED */
+static int apa102_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)
+{
+  FAR struct apa102_dev_s *priv = (FAR struct apa102_dev_s *)dev;
+  FAR uint16_t *src = (FAR uint16_t *)buffer;
+  int i;
+  int j;
 
-      apa102_write32(priv, (uint32_t) (*led | APA102_HEADER_FRAME));
-    }
+  ginfo("row_start: %d row_end: %d col_start: %d col_end: %d\n",
+         row_start, row_end, col_start, col_end);
 
-  /* Send an end of frame */
+  DEBUGASSERT(buffer && ((uintptr_t)buffer & 1) == 0);
 
-  apa102_write32(priv, APA102_END_FRAME);
+  /* Convert RGB565 to APA102 LED values */
 
-  for (i = 0; i < (1 + APA102_XRES * APA102_YRES / 32); i++)
+  for (i = row_start; i <= row_end; i++)
     {
-      apa102_write32(priv, 0);
+      for (j = col_start; j <= col_end; j++)
+        {
+          priv->fb[(i * APA102_XRES) + j] =
+            rgb565_apa102(*(src + (i * APA102_XRES) + j));
+        }
     }
 
+  /* Update the display with converted data */
+
+  apa102_refresh(priv);
+
   return OK;
 }
 
@@ -611,27 +681,9 @@ static inline void up_clear(FAR struct apa102_dev_s  *priv)
 
   memset(priv->fb, APA102_BLACK, 4 * APA102_FBSIZE);
 
-  /* Send a start of frame */
-
-  apa102_write32(priv, APA102_START_FRAME);
-
-  /* Clear all LEDs values in the matrix */
-
-  for (i = 0; i < (APA102_XRES * APA102_YRES); i++)
-    {
-      /* Then transfer 4 bytes per LED */
+  /* Update the display with framebuffer data */
 
-      apa102_write32(priv, (uint32_t) (APA102_BLACK | APA102_HEADER_FRAME));
-    }
-
-  /* Send an end of frame */
-
-  apa102_write32(priv, APA102_END_FRAME);
-
-  for (i = 0; i < (1 + APA102_XRES * APA102_YRES / 32); i++)
-    {
-      apa102_write32(priv, 0);
-    }
+  apa102_refresh(priv);
 }
 
 /****************************************************************************