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 2020/10/31 02:55:18 UTC

[incubator-nuttx] branch master updated: Add LCD character driver: allows interacting with LCD directly from userspace

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 278e7af  Add LCD character driver: allows interacting with LCD directly from userspace
278e7af is described below

commit 278e7af5e509cbfeda9cc5d93215f46c009ab938
Author: Matias N <ma...@protobits.dev>
AuthorDate: Thu Oct 29 21:59:29 2020 -0300

    Add LCD character driver: allows interacting with LCD directly from userspace
---
 drivers/lcd/Kconfig   |   8 ++
 drivers/lcd/Make.defs |   4 +
 drivers/lcd/lcd_dev.c | 273 ++++++++++++++++++++++++++++++++++++++++++++++++++
 drivers/lcd/lcd_dev.h | 105 +++++++++++++++++++
 4 files changed, 390 insertions(+)

diff --git a/drivers/lcd/Kconfig b/drivers/lcd/Kconfig
index 72e9ddd..ea939c6 100644
--- a/drivers/lcd/Kconfig
+++ b/drivers/lcd/Kconfig
@@ -24,6 +24,14 @@ config LCD_PACKEDMSFIRST
 
 comment "Common Graphic LCD Settings"
 
+config LCD_DEV
+  bool "LCD character device"
+  default n
+  ---help---
+    This option enables support for a character driver which exposes
+    LCD operations to userspace via ioctl() commands. This is useful when
+    not using NXGraphics but an alternative graphics library such as LVGL.
+
 config LCD_FRAMEBUFFER
 	bool "LCD framebuffer front end"
 	default n
diff --git a/drivers/lcd/Make.defs b/drivers/lcd/Make.defs
index 919dfb6..e5d667d 100644
--- a/drivers/lcd/Make.defs
+++ b/drivers/lcd/Make.defs
@@ -41,6 +41,10 @@ ifeq ($(CONFIG_LCD_FRAMEBUFFER),y)
   CSRCS += lcd_framebuffer.c
 endif
 
+ifeq ($(CONFIG_LCD_DEV),y)
+  CSRCS += lcd_dev.c
+endif
+
 # Include support for Graphics LCD drivers
 
 ifeq ($(CONFIG_LCD_FT80X),y)
diff --git a/drivers/lcd/lcd_dev.c b/drivers/lcd/lcd_dev.c
new file mode 100644
index 0000000..43d0ca8
--- /dev/null
+++ b/drivers/lcd/lcd_dev.c
@@ -0,0 +1,273 @@
+/****************************************************************************
+ * drivers/lcd/lcd_dev.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 <stdbool.h>
+#include <string.h>
+#include <poll.h>
+#include <errno.h>
+#include <debug.h>
+#include <stdio.h>
+
+#include <nuttx/kmalloc.h>
+#include <nuttx/signal.h>
+#include <nuttx/fs/fs.h>
+
+#include <nuttx/irq.h>
+#include <nuttx/board.h>
+
+#include "lcd_dev.h"
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* This structure provides the state of the lcd_dev driver */
+
+struct lcddev_dev_s
+{
+  FAR struct lcd_dev_s *lcd_ptr;
+  struct lcd_planeinfo_s planeinfo;
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Character driver methods */
+
+static int lcddev_open(FAR struct file *filep);
+static int lcddev_close(FAR struct file *filep);
+static int lcddev_ioctl(FAR struct file *filep, int cmd,
+                        unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const struct file_operations lcddev_fops =
+{
+  lcddev_open,  /* open */
+  lcddev_close, /* close */
+  NULL,         /* read */
+  NULL,         /* write */
+  NULL,         /* seek */
+  lcddev_ioctl, /* ioctl */
+  NULL          /* poll */
+#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
+  , NULL        /* unlink */
+#endif
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: lcddev_open
+ ****************************************************************************/
+
+static int lcddev_open(FAR struct file *filep)
+{
+  /* Nothing to do */
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: lcddev_close
+ ****************************************************************************/
+
+static int lcddev_close(FAR struct file *filep)
+{
+  /* Nothing to do */
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: lcddev_ioctl
+ ****************************************************************************/
+
+static int lcddev_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
+{
+  FAR struct lcddev_dev_s *priv;
+  int ret = OK;
+
+  priv  = (FAR struct lcddev_dev_s *)filep->f_inode->i_private;
+
+  switch (cmd)
+    {
+    case LCDDEVIO_GETRUN:
+      {
+        FAR struct lcddev_run_s *lcd_putrun =
+            (const FAR struct lcddev_run_s *)arg;
+
+        ret = priv->planeinfo.getrun(lcd_putrun->row, lcd_putrun->col,
+                                     lcd_putrun->data, lcd_putrun->npixels);
+      }
+      break;
+    case LCDDEVIO_PUTRUN:
+      {
+        const FAR struct lcddev_run_s *lcd_putrun =
+            (FAR struct lcddev_run_s *)arg;
+
+        ret = priv->planeinfo.putrun(lcd_putrun->row, lcd_putrun->col,
+                                     lcd_putrun->data, lcd_putrun->npixels);
+      }
+      break;
+    case LCDDEVIO_GETPOWER:
+      {
+        *((FAR int *)arg) = priv->lcd_ptr->getpower(priv->lcd_ptr);
+      }
+      break;
+    case LCDDEVIO_SETPOWER:
+      {
+        ret = priv->lcd_ptr->setpower(priv->lcd_ptr, (int)arg);
+      }
+      break;
+    case LCDDEVIO_GETCONTRAST:
+      {
+        *((FAR int *)arg) = priv->lcd_ptr->getcontrast(priv->lcd_ptr);
+      }
+      break;
+    case LCDDEVIO_SETCONTRAST:
+      {
+        ret = priv->lcd_ptr->setcontrast(priv->lcd_ptr, (unsigned int)arg);
+      }
+      break;
+    case LCDDEVIO_GETPLANEINFO:
+      {
+        *((FAR struct lcd_planeinfo_s *)arg) = priv->planeinfo;
+      }
+      break;
+    case LCDDEVIO_GETVIDEOINFO:
+      {
+        ret = priv->lcd_ptr->getvideoinfo(priv->lcd_ptr,
+                                          (FAR struct fb_videoinfo_s *)arg);
+      }
+      break;
+    case LCDDEVIO_SETPLANENO:
+      {
+        ret = priv->lcd_ptr->getplaneinfo(priv->lcd_ptr, (int)arg,
+                                          &priv->planeinfo);
+      }
+      break;
+#ifdef CONFIG_FB_CMAP
+    case LCDDEVIO_GETCMAP:
+      {
+        FAR struct fb_cmap_s *cmap = (FAR struct fb_cmap_s *)arg;
+
+        ret = priv->lcd_ptr->getcmap(priv->lcd_ptr, cmap);
+      }
+      break;
+    case LCDDEVIO_PUTCMAP:
+      {
+        FAR const struct fb_cmap_s *cmap = (FAR const struct fb_cmap_s *)arg;
+
+        ret = priv->lcd_ptr->putcmap(priv->lcd_ptr, cmap);
+      }
+      break;
+#endif
+#ifdef CONFIG_FB_HWCURSOR
+    case LCDDEVIO_GETCURSOR:
+      {
+        FAR struct fb_cursorattrib_s *attrib =
+            (FAR struct fb_cursorattrib_s *)arg;
+
+        ret = priv->lcd_ptr->getcursor(priv->lcd_ptr, attrib);
+      }
+      break;
+    case LCDDEVIO_SETCURSOR:
+      {
+        FAR struct fb_setcursor_s *settings =
+            (FAR struct fb_setcursor_s *)arg;
+
+        ret = priv->lcd_ptr->setcursor(priv->lcd_ptr, settings);
+      }
+      break;
+#endif
+    default:
+      ret = -EINVAL;
+      break;
+    }
+
+  return ret;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: lcddev_register
+ *
+ * Description:
+ *   Register the LCD character driver as /dev/lcdN.
+ *
+ * Input Parameters:
+ *   devno - The LCD device number.
+ *
+ * Returned Value:
+ *   Zero (OK) is returned on success.  Otherwise a negated errno value is
+ *   returned to indicate the nature of the failure.
+ *
+ ****************************************************************************/
+
+int lcddev_register(int devno)
+{
+  FAR struct lcddev_dev_s *priv;
+  int ret = OK;
+  char devname[16];
+
+  /* Allocate a new lcd_dev driver instance */
+
+  priv = (FAR struct lcddev_dev_s *)kmm_zalloc(sizeof(struct lcddev_dev_s));
+
+  if (!priv)
+    {
+      return -ENOMEM;
+    }
+
+  priv->lcd_ptr = board_lcd_getdev(devno);
+  ret = priv->lcd_ptr->getplaneinfo(priv->lcd_ptr, 0, &priv->planeinfo);
+  if (ret < 0)
+    {
+      goto err;
+    }
+
+  snprintf(devname, sizeof(devname), "/dev/lcd%i", devno);
+  ret = register_driver(devname, &lcddev_fops, 0666, priv);
+  if (ret < 0)
+    {
+      goto err;
+    }
+
+  return ret;
+err:
+  kmm_free(priv);
+  return ret;
+}
diff --git a/drivers/lcd/lcd_dev.h b/drivers/lcd/lcd_dev.h
new file mode 100644
index 0000000..85fa67b
--- /dev/null
+++ b/drivers/lcd/lcd_dev.h
@@ -0,0 +1,105 @@
+/****************************************************************************
+ * drivers/lcd/lcd_dev.h
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+#ifndef __DRIVERS_LCD_LCD_DEV_H
+#define __DRIVERS_LCD_LCD_DEV_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/input/ioctl.h>
+#include <nuttx/lcd/lcd.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Type Definitions
+ ****************************************************************************/
+
+#define LCDDEVIO_PUTRUN       _LCDIOC(0)  /* Arg: const struct lcddev_putrun_s* */
+#define LCDDEVIO_GETRUN       _LCDIOC(1)  /* Arg: struct lcddev_putrun_s* */
+#define LCDDEVIO_GETPOWER     _LCDIOC(2)  /* Arg: int* */
+#define LCDDEVIO_SETPOWER     _LCDIOC(3)  /* Arg: int */
+#define LCDDEVIO_GETCONTRAST  _LCDIOC(4)  /* Arg: int* */
+#define LCDDEVIO_SETCONTRAST  _LCDIOC(5)  /* Arg: unsigned int */
+#define LCDDEVIO_GETPLANEINFO _LCDIOC(6)  /* Arg: struct lcd_planeinfo_s* */
+#define LCDDEVIO_GETVIDEOINFO _LCDIOC(7)  /* Arg: struct fb_videoinfo_s* */
+#define LCDDEVIO_SETPLANENO   _LCDIOC(8)  /* Arg: int */
+
+#ifdef CONFIG_FB_CMAP
+#define LCDDEVIO_GETCMAP      _LCDIOC(9)  /* Arg: struct fb_cmap_s* */
+#define LCDDEVIO_PUTCMAP      _LCDIOC(10) /* Arg: const struct fb_cmap_s* */
+#endif
+
+#ifdef CONFIG_FB_HWCURSOR
+#define LCDDEVIO_GETCURSOR    _LCDIOC(11) /* Arg: struct fb_cursorattrib_s* */
+#define LCDDEVIO_SETCURSOR    _LCDIOC(12) /* Arg: struct fb_setcursor_s* */
+#endif
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+#ifdef __cplusplus
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+struct lcddev_run_s
+{
+  fb_coord_t row, col;
+  FAR uint8_t *data;
+  size_t npixels;
+};
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: lcddev_register
+ *
+ * Description:
+ *   Register the lcd_dev character driver as the specified device.
+ *
+ * Input Parameters:
+ *   devno - The LCD device number.
+ *
+ * Returned Value:
+ *   Zero (OK) is returned on success.  Otherwise a negated errno value is
+ *   returned to indicate the nature of the failure.
+ *
+ ****************************************************************************/
+
+int lcddev_register(int devno);
+
+#undef EXTERN
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __DRIVERS_LCD_LCD_DEV_H */