You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by bt...@apache.org on 2021/01/17 05:04:59 UTC

[incubator-nuttx] 07/07: nrf52 GPIO: set GPIO drive setting and missing input buffer configuration

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

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

commit 93ef2e71748e8ad16d33d18fdca2ba55d9eaf0a5
Author: Matias N <ma...@protobits.dev>
AuthorDate: Sat Jan 16 19:33:02 2021 -0300

    nrf52 GPIO: set GPIO drive setting and missing input buffer configuration
---
 arch/arm/src/nrf52/nrf52_gpio.c | 83 ++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 81 insertions(+), 2 deletions(-)

diff --git a/arch/arm/src/nrf52/nrf52_gpio.c b/arch/arm/src/nrf52/nrf52_gpio.c
index 6f5625c..83e70b0 100644
--- a/arch/arm/src/nrf52/nrf52_gpio.c
+++ b/arch/arm/src/nrf52/nrf52_gpio.c
@@ -100,6 +100,11 @@ static inline void nrf52_gpio_input(unsigned int port, unsigned int pin)
   /* Configure the pin as an input */
 
   putreg32(1U << pin, offset);
+
+  /* Enable input buffer */
+
+  offset = nrf52_gpio_regget(port, NRF52_GPIO_PIN_CNF_OFFSET(pin));
+  modifyreg32(offset, GPIO_CNF_INPUT, 0);
 }
 
 /****************************************************************************
@@ -115,6 +120,11 @@ static inline void nrf52_gpio_output(nrf52_pinset_t cfgset,
 {
   uint32_t offset;
 
+  /* Disable input buffer */
+
+  offset = nrf52_gpio_regget(port, NRF52_GPIO_PIN_CNF_OFFSET(pin));
+  modifyreg32(offset, 0, GPIO_CNF_INPUT);
+
   offset = nrf52_gpio_regget(port, NRF52_GPIO_DIRSET_OFFSET);
 
   nrf52_gpio_write(cfgset, ((cfgset & GPIO_VALUE) != GPIO_VALUE_ZERO));
@@ -193,6 +203,59 @@ static inline void nrf52_gpio_sense(nrf52_pinset_t cfgset,
 }
 
 /****************************************************************************
+ * Name: nrf52_gpio_drive
+ *
+ * Description:
+ *   Set DRIVE configuration for a pin
+ *
+ ****************************************************************************/
+
+static inline void nrf52_gpio_drive(nrf52_pinset_t cfgset,
+                                    unsigned int port, unsigned int pin)
+{
+  uint32_t drive;
+  uint32_t regval;
+  uint32_t offset;
+
+  drive = cfgset & GPIO_DRIVE_MASK;
+
+  offset = nrf52_gpio_regget(port, NRF52_GPIO_PIN_CNF_OFFSET(pin));
+  regval = getreg32(offset);
+
+  regval &= ~GPIO_CNF_DRIVE_MASK;
+
+  switch (drive)
+    {
+      case GPIO_DRIVE_S0S1:
+        regval |= GPIO_CNF_DRIVE_S0S1;
+        break;
+      case GPIO_DRIVE_S0H1:
+        regval |= GPIO_CNF_DRIVE_S0H1;
+        break;
+      case GPIO_DRIVE_S0D1:
+        regval |= GPIO_CNF_DRIVE_S0D1;
+        break;
+      case GPIO_DRIVE_H0D1:
+        regval |= GPIO_CNF_DRIVE_H0D1;
+        break;
+      case GPIO_DRIVE_H0H1:
+        regval |= GPIO_CNF_DRIVE_H0H1;
+        break;
+      case GPIO_DRIVE_H0S1:
+        regval |= GPIO_CNF_DRIVE_H0S1;
+        break;
+      case GPIO_DRIVE_D0H1:
+        regval |= GPIO_CNF_DRIVE_D0H1;
+        break;
+      case GPIO_DRIVE_D0S1:
+        regval |= GPIO_CNF_DRIVE_D0S1;
+        break;
+    }
+
+  putreg32(regval, offset);
+}
+
+/****************************************************************************
  * Public Functions
  ****************************************************************************/
 
@@ -208,6 +271,8 @@ int nrf52_gpio_config(nrf52_pinset_t cfgset)
 {
   unsigned int port;
   unsigned int pin;
+  irqstate_t flags;
+  int ret = OK;
 
   /* Verify that this hardware supports the select GPIO port */
 
@@ -220,6 +285,8 @@ int nrf52_gpio_config(nrf52_pinset_t cfgset)
 
       pin = GPIO_PIN_DECODE(cfgset);
 
+      flags = spin_lock_irqsave();
+
       /* First, configure the port as a generic input so that we have a
        * known starting point and consistent behavior during the re-
        * configuration.
@@ -231,6 +298,12 @@ int nrf52_gpio_config(nrf52_pinset_t cfgset)
 
       nrf52_gpio_mode(cfgset, port, pin);
 
+      /* Set the drive bits (needed also for input pins
+       * for some peripherals).
+       */
+
+      nrf52_gpio_drive(cfgset, port, pin);
+
       /* Handle according to pin function */
 
       switch (cfgset & GPIO_FUNC_MASK)
@@ -244,11 +317,17 @@ int nrf52_gpio_config(nrf52_pinset_t cfgset)
           break;
 
         default:
-          return -EINVAL;
+          ret = -EINVAL;
         }
+
+      spin_unlock_irqrestore(flags);
+    }
+  else
+    {
+      ret = -EINVAL;
     }
 
-  return OK;
+  return ret;
 }
 
 /****************************************************************************