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/03/19 09:37:24 UTC

[incubator-nuttx] branch master updated: boards/arm/samv7/same70-qmtech: add gpio driver support

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 c01cd62  boards/arm/samv7/same70-qmtech: add gpio driver support
c01cd62 is described below

commit c01cd62666f7220d1c0e6303f7f63e982e80ecbd
Author: Petro Karashchenko <pe...@gmail.com>
AuthorDate: Fri Mar 18 15:47:58 2022 +0100

    boards/arm/samv7/same70-qmtech: add gpio driver support
    
    Signed-off-by: Petro Karashchenko <pe...@gmail.com>
---
 boards/arm/samv7/same70-qmtech/src/Make.defs       |   4 +
 boards/arm/samv7/same70-qmtech/src/sam_bringup.c   |   8 +
 boards/arm/samv7/same70-qmtech/src/sam_gpio.c      | 354 +++++++++++++++++++++
 boards/arm/samv7/same70-qmtech/src/same70-qmtech.h |  18 ++
 4 files changed, 384 insertions(+)

diff --git a/boards/arm/samv7/same70-qmtech/src/Make.defs b/boards/arm/samv7/same70-qmtech/src/Make.defs
index ab266c0..ca7b971 100644
--- a/boards/arm/samv7/same70-qmtech/src/Make.defs
+++ b/boards/arm/samv7/same70-qmtech/src/Make.defs
@@ -54,6 +54,10 @@ ifneq (,$(findstring y,$(CONFIG_SAMV7_DAC0) $(CONFIG_SAMV7_DAC1)))
 CSRCS += sam_dac.c
 endif
 
+ifeq ($(CONFIG_DEV_GPIO),y)
+CSRCS += sam_gpio.c
+endif
+
 .PHONY = context distclean
 
 $(SCRIPTOUT): $(LDSCRIPT_TEMPLATE) $(CONFIGFILE)
diff --git a/boards/arm/samv7/same70-qmtech/src/sam_bringup.c b/boards/arm/samv7/same70-qmtech/src/sam_bringup.c
index 4b432d2..02a73d8 100644
--- a/boards/arm/samv7/same70-qmtech/src/sam_bringup.c
+++ b/boards/arm/samv7/same70-qmtech/src/sam_bringup.c
@@ -266,6 +266,14 @@ int sam_bringup(void)
     }
 #endif
 
+#if defined(CONFIG_DEV_GPIO)
+  ret = sam_gpio_initialize();
+  if (ret < 0)
+    {
+      syslog(LOG_ERR, "ERROR: sam_gpio_initialize failed: %d\n", ret);
+    }
+#endif
+
 #if defined(CONFIG_TIMER) && defined(CONFIG_SAMV7_TC0)
   ret = sam_timer_initialize("/dev/timer0", TC_CHAN2);
   if (ret < 0)
diff --git a/boards/arm/samv7/same70-qmtech/src/sam_gpio.c b/boards/arm/samv7/same70-qmtech/src/sam_gpio.c
new file mode 100644
index 0000000..b5e8ce9
--- /dev/null
+++ b/boards/arm/samv7/same70-qmtech/src/sam_gpio.c
@@ -0,0 +1,354 @@
+/****************************************************************************
+ * boards/arm/samv7/same70-qmtech/src/sam_gpio.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 <stdbool.h>
+#include <assert.h>
+#include <debug.h>
+#include <errno.h>
+
+#include <nuttx/ioexpander/gpio.h>
+
+#include "sam_gpio.h"
+
+#include "same70-qmtech.h"
+
+#ifdef CONFIG_DEV_GPIO
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct samgpio_dev_s
+{
+  struct gpio_dev_s gpio;
+  uint8_t           id;
+};
+
+struct samgpint_dev_s
+{
+  struct samgpio_dev_s samgpio;
+  pin_interrupt_t      callback;
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+#if BOARD_NGPIOIN > 0
+static int gpin_read(FAR struct gpio_dev_s *dev, FAR bool *value);
+#endif
+#if BOARD_NGPIOOUT > 0
+static int gpout_read(FAR struct gpio_dev_s *dev, FAR bool *value);
+static int gpout_write(FAR struct gpio_dev_s *dev, bool value);
+#endif
+#if BOARD_NGPIOINT > 0
+static int gpint_read(FAR struct gpio_dev_s *dev, FAR bool *value);
+static int gpint_attach(FAR struct gpio_dev_s *dev,
+                        pin_interrupt_t callback);
+static int gpint_enable(FAR struct gpio_dev_s *dev, bool enable);
+#endif
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+#if BOARD_NGPIOIN > 0
+static const struct gpio_operations_s gpin_ops =
+{
+  .go_read   = gpin_read,
+  .go_write  = NULL,
+  .go_attach = NULL,
+  .go_enable = NULL,
+};
+#endif
+
+#if BOARD_NGPIOOUT > 0
+static const struct gpio_operations_s gpout_ops =
+{
+  .go_read   = gpout_read,
+  .go_write  = gpout_write,
+  .go_attach = NULL,
+  .go_enable = NULL,
+};
+#endif
+
+#if BOARD_NGPIOINT > 0
+static const struct gpio_operations_s gpint_ops =
+{
+  .go_read   = gpint_read,
+  .go_write  = NULL,
+  .go_attach = gpint_attach,
+  .go_enable = gpint_enable,
+};
+#endif
+
+#if BOARD_NGPIOIN > 0
+/* This array maps the GPIO pins used as INPUT */
+
+static const gpio_pinset_t g_gpioinputs[BOARD_NGPIOIN] =
+{
+  GPIO_IN1,
+};
+
+static struct samgpio_dev_s g_gpin[BOARD_NGPIOIN];
+#endif
+
+#if BOARD_NGPIOOUT > 0
+/* This array maps the GPIO pins used as OUTPUT */
+
+static const gpio_pinset_t g_gpiooutputs[BOARD_NGPIOOUT] =
+{
+  GPIO_OUT1
+};
+
+static struct samgpio_dev_s g_gpout[BOARD_NGPIOOUT];
+#endif
+
+#if BOARD_NGPIOINT > 0
+/* This array maps the GPIO pins used as INTERRUPT INPUTS */
+
+static const gpio_pinset_t g_gpiointinputs[BOARD_NGPIOINT] =
+{
+  GPIO_INT1
+};
+
+static const int g_gpiointirqs[BOARD_NGPIOINT] =
+{
+  GPIO_IRQ_INT1
+};
+
+static struct samgpint_dev_s g_gpint[BOARD_NGPIOINT];
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+#if BOARD_NGPIOIN > 0
+
+static int gpin_read(FAR struct gpio_dev_s *dev, FAR bool *value)
+{
+  FAR struct samgpio_dev_s *samgpio = (FAR struct samgpio_dev_s *)dev;
+
+  DEBUGASSERT(samgpio != NULL && value != NULL);
+  DEBUGASSERT(samgpio->id < BOARD_NGPIOIN);
+  gpioinfo("Reading...");
+
+  *value = sam_gpioread(g_gpioinputs[samgpio->id]);
+  return OK;
+}
+
+#endif
+
+#if BOARD_NGPIOOUT > 0
+
+static int gpout_read(FAR struct gpio_dev_s *dev, FAR bool *value)
+{
+  FAR struct samgpio_dev_s *samgpio = (FAR struct samgpio_dev_s *)dev;
+
+  DEBUGASSERT(samgpio != NULL && value != NULL);
+  DEBUGASSERT(samgpio->id < BOARD_NGPIOOUT);
+  gpioinfo("Reading...");
+
+  *value = sam_gpioread(g_gpiooutputs[samgpio->id]);
+  return OK;
+}
+
+static int gpout_write(FAR struct gpio_dev_s *dev, bool value)
+{
+  FAR struct samgpio_dev_s *samgpio = (FAR struct samgpio_dev_s *)dev;
+
+  DEBUGASSERT(samgpio != NULL);
+  DEBUGASSERT(samgpio->id < BOARD_NGPIOOUT);
+  gpioinfo("Writing %d", (int)value);
+
+  sam_gpiowrite(g_gpiooutputs[samgpio->id], value);
+  return OK;
+}
+
+#endif
+
+#if BOARD_NGPIOINT > 0
+
+static int samgpio_interrupt(int irq, void *context, void *arg)
+{
+  FAR struct samgpint_dev_s *samgpint = (FAR struct samgpint_dev_s *)arg;
+
+  DEBUGASSERT(samgpint != NULL && samgpint->callback != NULL);
+  gpioinfo("Interrupt callback=%p", samgpint->callback);
+
+  samgpint->callback(&samgpint->samgpio.gpio, samgpint->samgpio.id);
+  return OK;
+}
+
+static int gpint_read(FAR struct gpio_dev_s *dev, FAR bool *value)
+{
+  FAR struct samgpint_dev_s *samgpint = (FAR struct samgpint_dev_s *)dev;
+
+  DEBUGASSERT(samgpint != NULL && value != NULL);
+  DEBUGASSERT(samgpint->samgpio.id < BOARD_NGPIOINT);
+  gpioinfo("Reading int pin...");
+
+  *value = sam_gpioread(g_gpiointinputs[samgpint->samgpio.id]);
+  return OK;
+}
+
+static int gpint_attach(FAR struct gpio_dev_s *dev,
+                        pin_interrupt_t callback)
+{
+  FAR struct samgpint_dev_s *samgpint = (FAR struct samgpint_dev_s *)dev;
+  irqstate_t flags;
+
+  gpioinfo("Attaching the callback");
+
+  flags = enter_critical_section();
+
+  sam_gpioirq(g_gpiointinputs[samgpint->samgpio.id]);
+
+  /* Make sure the interrupt is disabled */
+
+  irq_attach(g_gpiointirqs[samgpint->samgpio.id], samgpio_interrupt,
+             &g_gpint[samgpint->samgpio.id]);
+
+  leave_critical_section(flags);
+  gpioinfo("Attach %p", callback);
+  samgpint->callback = callback;
+  return OK;
+}
+
+static int gpint_enable(FAR struct gpio_dev_s *dev, bool enable)
+{
+  FAR struct samgpint_dev_s *samgpint = (FAR struct samgpint_dev_s *)dev;
+  irqstate_t flags;
+
+  flags = enter_critical_section();
+  if (enable)
+    {
+      if (samgpint->callback != NULL)
+        {
+          gpioinfo("Enabling the interrupt");
+          sam_gpioirqenable(g_gpiointirqs[samgpint->samgpio.id]);
+        }
+    }
+  else
+    {
+      sam_gpioirqdisable(g_gpiointirqs[samgpint->samgpio.id]);
+      gpioinfo("Disable the interrupt");
+    }
+
+  leave_critical_section(flags);
+  return OK;
+}
+
+#endif
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: sam_gpio_initialize
+ *
+ * Description:
+ *   Initialize GPIO drivers for use with /apps/examples/gpio
+ *
+ ****************************************************************************/
+
+int sam_gpio_initialize(void)
+{
+#ifdef CONFIG_SAME70QMTECH_SN74HC595D_IOEXPANDER
+  FAR struct ioexpander_dev_s *ioe;
+#endif
+  int pincount = 0;
+  int i;
+  int ret = 0;
+
+#if BOARD_NGPIOIN > 0
+  for (i = 0; i < BOARD_NGPIOIN; i++, pincount++)
+    {
+      /* Setup and register the GPIO pin */
+
+      g_gpin[i].gpio.gp_pintype = GPIO_INPUT_PIN;
+      g_gpin[i].gpio.gp_ops     = &gpin_ops;
+      g_gpin[i].id              = i;
+      ret = gpio_pin_register(&g_gpin[i].gpio, pincount);
+      if (ret < 0)
+        {
+          gpioerr("GPIOIN(%d): gpio_pin_register failed: %d", i, ret);
+          return ret;
+        }
+
+      /* Configure the pin that will be used as input */
+
+      sam_configgpio(g_gpioinputs[i]);
+    }
+#endif
+
+#if BOARD_NGPIOOUT > 0
+  for (i = 0; i < BOARD_NGPIOOUT; i++, pincount++)
+    {
+      /* Setup and register the GPIO pin */
+
+      g_gpout[i].gpio.gp_pintype = GPIO_OUTPUT_PIN;
+      g_gpout[i].gpio.gp_ops     = &gpout_ops;
+      g_gpout[i].id              = i;
+      ret = gpio_pin_register(&g_gpout[i].gpio, pincount);
+      if (ret < 0)
+        {
+          gpioerr("GPIOOUT(%d): gpio_pin_register failed: %d", i, ret);
+          return ret;
+        }
+
+      /* Configure the pin that will be used as output */
+
+      sam_configgpio(g_gpiooutputs[i]);
+    }
+#endif
+
+#if BOARD_NGPIOINT > 0
+  for (i = 0; i < BOARD_NGPIOINT; i++, pincount++)
+    {
+      /* Setup and register the GPIO pin */
+
+      g_gpint[i].samgpio.gpio.gp_pintype = GPIO_INTERRUPT_PIN;
+      g_gpint[i].samgpio.gpio.gp_ops     = &gpint_ops;
+      g_gpint[i].samgpio.id              = i;
+      ret = gpio_pin_register(&g_gpint[i].samgpio.gpio, pincount);
+      if (ret < 0)
+        {
+          gpioerr("GPIOINT(%d): gpio_pin_register failed: %d", i, ret);
+          return ret;
+        }
+
+      /* Configure the pin that will be used as interrupt input */
+
+      sam_configgpio(g_gpiointinputs[i]);
+    }
+#endif
+
+  return ret;
+}
+#endif
diff --git a/boards/arm/samv7/same70-qmtech/src/same70-qmtech.h b/boards/arm/samv7/same70-qmtech/src/same70-qmtech.h
index 95d8070..ea91f82 100644
--- a/boards/arm/samv7/same70-qmtech/src/same70-qmtech.h
+++ b/boards/arm/samv7/same70-qmtech/src/same70-qmtech.h
@@ -169,6 +169,12 @@
                         GPIO_INT_BOTHEDGES | GPIO_PORT_PIOD | GPIO_PIN17)
 #define IRQ_HSMCI0_CD  SAM_IRQ_PD17
 
+/* GPIO pins used by the GPIO Subsystem */
+
+#define BOARD_NGPIOIN     0 /* Amount of GPIO Input pins */
+#define BOARD_NGPIOOUT    0 /* Amount of GPIO Output pins */
+#define BOARD_NGPIOINT    0 /* Amount of GPIO Input w/ Interruption pins */
+
 /****************************************************************************
  * Public Types
  ****************************************************************************/
@@ -244,5 +250,17 @@ void sam_spidev_initialize(void);
 int sam_can_setup(void);
 #endif
 
+/****************************************************************************
+ * Name: sam_gpio_initialize
+ *
+ * Description:
+ *   Initialize GPIO drivers for use with /apps/examples/gpio
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_DEV_GPIO
+int sam_gpio_initialize(void);
+#endif
+
 #endif /* __ASSEMBLY__ */
 #endif /* __BOARDS_ARM_SAMV7_SAME70_QMTECH_SRC_SAME70_QMTECH_H */