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/07/07 13:34:33 UTC
[incubator-nuttx] branch master updated: gpio: extend
gpio_pintype_e for pulldown/up and opendrain
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 a349595 gpio: extend gpio_pintype_e for pulldown/up and opendrain
a349595 is described below
commit a349595316562ff7bef8147215c1442f9ffa1e54
Author: Beat Küng <be...@gmx.net>
AuthorDate: Thu Jul 2 12:47:58 2020 +0200
gpio: extend gpio_pintype_e for pulldown/up and opendrain
- fix code style
- fix bool conversion when calling go_read()
---
arch/sim/src/sim/up_ioexpander.c | 10 +++++++---
drivers/analog/lmp92001.c | 10 +++++++---
drivers/ioexpander/gpio.c | 14 +++++++++++---
drivers/ioexpander/gpio_lower_half.c | 26 +++++++++++++++++++++++---
drivers/ioexpander/pca9538.c | 6 ++++++
drivers/ioexpander/pca9555.c | 6 ++++++
drivers/ioexpander/pcf8574.c | 10 +++++++---
drivers/ioexpander/skeleton.c | 14 ++++++++++----
drivers/ioexpander/tca64xx.c | 10 +++++++---
include/nuttx/ioexpander/gpio.h | 9 ++++++---
include/nuttx/ioexpander/ioexpander.h | 18 +++++++++++-------
11 files changed, 101 insertions(+), 32 deletions(-)
diff --git a/arch/sim/src/sim/up_ioexpander.c b/arch/sim/src/sim/up_ioexpander.c
index 0371c89..578216d 100644
--- a/arch/sim/src/sim/up_ioexpander.c
+++ b/arch/sim/src/sim/up_ioexpander.c
@@ -199,9 +199,13 @@ static int sim_direction(FAR struct ioexpander_dev_s *dev, uint8_t pin,
{
FAR struct sim_dev_s *priv = (FAR struct sim_dev_s *)dev;
- DEBUGASSERT(priv != NULL && pin < CONFIG_IOEXPANDER_NPINS &&
- (direction == IOEXPANDER_DIRECTION_IN ||
- direction == IOEXPANDER_DIRECTION_OUT));
+ if (direction != IOEXPANDER_DIRECTION_IN &&
+ direction != IOEXPANDER_DIRECTION_OUT)
+ {
+ return -EINVAL;
+ }
+
+ DEBUGASSERT(priv != NULL && pin < CONFIG_IOEXPANDER_NPINS);
gpioinfo("pin=%u direction=%s\n",
pin, (direction == IOEXPANDER_DIRECTION_IN) ? "IN" : "OUT");
diff --git a/drivers/analog/lmp92001.c b/drivers/analog/lmp92001.c
index 212cb04..47469f7 100644
--- a/drivers/analog/lmp92001.c
+++ b/drivers/analog/lmp92001.c
@@ -1214,9 +1214,13 @@ static int lmp92001_gpio_direction(FAR struct ioexpander_dev_s *dev,
int ret;
- DEBUGASSERT(priv != NULL && pin < LMP92001_GPIO_MAX_PINS &&
- (direction == IOEXPANDER_DIRECTION_IN ||
- direction == IOEXPANDER_DIRECTION_OUT));
+ if (direction != IOEXPANDER_DIRECTION_IN &&
+ direction != IOEXPANDER_DIRECTION_OUT)
+ {
+ return -EINVAL;
+ }
+
+ DEBUGASSERT(priv != NULL && pin < LMP92001_GPIO_MAX_PINS);
gpioinfo("I2C addr=%02x pin=%u direction=%s\n",
priv->addr, pin,
diff --git a/drivers/ioexpander/gpio.c b/drivers/ioexpander/gpio.c
index 864e4d7..4b17d55 100644
--- a/drivers/ioexpander/gpio.c
+++ b/drivers/ioexpander/gpio.c
@@ -187,7 +187,7 @@ static ssize_t gpio_read(FAR struct file *filep, FAR char *buffer,
/* Read the GPIO value */
- ret = dev->gp_ops->go_read(dev, (FAR uint8_t *)&buffer[0]);
+ ret = dev->gp_ops->go_read(dev, (FAR bool *)&buffer[0]);
if (ret < 0)
{
return ret;
@@ -229,7 +229,8 @@ static ssize_t gpio_write(FAR struct file *filep, FAR const char *buffer,
/* Check if this pin is write-able */
- if (dev->gp_pintype != GPIO_OUTPUT_PIN)
+ if (dev->gp_pintype != GPIO_OUTPUT_PIN &&
+ dev->gp_pintype != GPIO_OUTPUT_PIN_OPENDRAIN)
{
return -EACCES;
}
@@ -336,7 +337,8 @@ static int gpio_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
*/
case GPIOC_WRITE:
- if (dev->gp_pintype == GPIO_OUTPUT_PIN)
+ if (dev->gp_pintype == GPIO_OUTPUT_PIN ||
+ dev->gp_pintype == GPIO_OUTPUT_PIN_OPENDRAIN)
{
DEBUGASSERT(arg == 0ul || arg == 1ul);
ret = dev->gp_ops->go_write(dev, (bool)arg);
@@ -544,6 +546,8 @@ int gpio_pin_register(FAR struct gpio_dev_s *dev, int minor)
switch (dev->gp_pintype)
{
case GPIO_INPUT_PIN:
+ case GPIO_INPUT_PIN_PULLUP:
+ case GPIO_INPUT_PIN_PULLDOWN:
{
DEBUGASSERT(dev->gp_ops->go_read != NULL);
fmt = "/dev/gpin%u";
@@ -551,6 +555,7 @@ int gpio_pin_register(FAR struct gpio_dev_s *dev, int minor)
break;
case GPIO_OUTPUT_PIN:
+ case GPIO_OUTPUT_PIN_OPENDRAIN:
{
DEBUGASSERT(dev->gp_ops->go_read != NULL &&
dev->gp_ops->go_write != NULL);
@@ -606,12 +611,15 @@ void gpio_pin_unregister(FAR struct gpio_dev_s *dev, int minor)
switch (dev->gp_pintype)
{
case GPIO_INPUT_PIN:
+ case GPIO_INPUT_PIN_PULLUP:
+ case GPIO_INPUT_PIN_PULLDOWN:
{
fmt = "/dev/gpin%u";
}
break;
case GPIO_OUTPUT_PIN:
+ case GPIO_OUTPUT_PIN_OPENDRAIN:
{
fmt = "/dev/gpout%u";
}
diff --git a/drivers/ioexpander/gpio_lower_half.c b/drivers/ioexpander/gpio_lower_half.c
index 3a58951..fad949e 100644
--- a/drivers/ioexpander/gpio_lower_half.c
+++ b/drivers/ioexpander/gpio_lower_half.c
@@ -85,7 +85,8 @@ static int gplh_handler(FAR struct ioexpander_dev_s *ioe,
static int gplh_read(FAR struct gpio_dev_s *gpio, FAR bool *value);
static int gplh_write(FAR struct gpio_dev_s *gpio, bool value);
#ifdef CONFIG_IOEXPANDER_INT_ENABLE
-static int gplh_attach(FAR struct gpio_dev_s *gpio, pin_interrupt_t callback);
+static int gplh_attach(FAR struct gpio_dev_s *gpio,
+ pin_interrupt_t callback);
static int gplh_enable(FAR struct gpio_dev_s *gpio, bool enable);
#endif
static int gplh_setpintype(FAR struct gpio_dev_s *gpio,
@@ -118,6 +119,8 @@ static const struct gpio_operations_s g_gplh_ops =
static const uint32_t g_gplh_inttype[] =
{
[GPIO_INPUT_PIN] = IOEXPANDER_VAL_DISABLE,
+ [GPIO_INPUT_PIN_PULLUP] = IOEXPANDER_VAL_DISABLE,
+ [GPIO_INPUT_PIN_PULLDOWN] = IOEXPANDER_VAL_DISABLE,
[GPIO_INTERRUPT_PIN] = CONFIG_GPIO_LOWER_HALF_INTTYPE,
[GPIO_INTERRUPT_HIGH_PIN] = IOEXPANDER_VAL_HIGH,
[GPIO_INTERRUPT_LOW_PIN] = IOEXPANDER_VAL_LOW,
@@ -332,7 +335,8 @@ static int gplh_enable(FAR struct gpio_dev_s *gpio, bool enable)
*
****************************************************************************/
-static int gplh_setpintype(FAR struct gpio_dev_s *gpio, enum gpio_pintype_e pintype)
+static int gplh_setpintype(FAR struct gpio_dev_s *gpio,
+ enum gpio_pintype_e pintype)
{
FAR struct gplh_dev_s *priv = (FAR struct gplh_dev_s *)gpio;
FAR struct ioexpander_dev_s *ioe = priv->ioe;
@@ -346,9 +350,25 @@ static int gplh_setpintype(FAR struct gpio_dev_s *gpio, enum gpio_pintype_e pint
{
IOEXP_SETDIRECTION(ioe, pin, IOEXPANDER_DIRECTION_OUT);
}
+ else if (pintype == GPIO_OUTPUT_PIN_OPENDRAIN)
+ {
+ IOEXP_SETDIRECTION(ioe, pin, IOEXPANDER_DIRECTION_OUT_OPENDRAIN);
+ }
else
{
- IOEXP_SETDIRECTION(ioe, pin, IOEXPANDER_DIRECTION_IN);
+ if (pintype == GPIO_INPUT_PIN)
+ {
+ IOEXP_SETDIRECTION(ioe, pin, IOEXPANDER_DIRECTION_IN);
+ }
+ else if (pintype == GPIO_INPUT_PIN_PULLUP)
+ {
+ IOEXP_SETDIRECTION(ioe, pin, IOEXPANDER_DIRECTION_IN_PULLUP);
+ }
+ else
+ {
+ IOEXP_SETDIRECTION(ioe, pin, IOEXPANDER_DIRECTION_IN_PULLDOWN);
+ }
+
IOEXP_SETOPTION(ioe, pin, IOEXPANDER_OPTION_INTCFG,
(FAR void *)g_gplh_inttype[pintype]);
}
diff --git a/drivers/ioexpander/pca9538.c b/drivers/ioexpander/pca9538.c
index e6edc7f..e4d70b9 100644
--- a/drivers/ioexpander/pca9538.c
+++ b/drivers/ioexpander/pca9538.c
@@ -309,6 +309,12 @@ static int pca9538_direction(FAR struct ioexpander_dev_s *dev, uint8_t pin,
FAR struct pca9538_dev_s *pca = (FAR struct pca9538_dev_s *)dev;
int ret;
+ if (direction != IOEXPANDER_DIRECTION_IN &&
+ direction != IOEXPANDER_DIRECTION_OUT)
+ {
+ return -EINVAL;
+ }
+
/* Get exclusive access to the PCA555 */
ret = pca9538_lock(pca);
diff --git a/drivers/ioexpander/pca9555.c b/drivers/ioexpander/pca9555.c
index 07a45d0..916c6d6 100644
--- a/drivers/ioexpander/pca9555.c
+++ b/drivers/ioexpander/pca9555.c
@@ -337,6 +337,12 @@ static int pca9555_direction(FAR struct ioexpander_dev_s *dev, uint8_t pin,
FAR struct pca9555_dev_s *pca = (FAR struct pca9555_dev_s *)dev;
int ret;
+ if (direction != IOEXPANDER_DIRECTION_IN &&
+ direction != IOEXPANDER_DIRECTION_OUT)
+ {
+ return -EINVAL;
+ }
+
/* Get exclusive access to the PCA555 */
ret = pca9555_lock(pca);
diff --git a/drivers/ioexpander/pcf8574.c b/drivers/ioexpander/pcf8574.c
index 4824f50..886fef9 100644
--- a/drivers/ioexpander/pcf8574.c
+++ b/drivers/ioexpander/pcf8574.c
@@ -256,9 +256,13 @@ static int pcf8574_direction(FAR struct ioexpander_dev_s *dev, uint8_t pin,
FAR struct pcf8574_dev_s *priv = (FAR struct pcf8574_dev_s *)dev;
int ret;
- DEBUGASSERT(priv != NULL && priv->config != NULL && pin < 8 &&
- (direction == IOEXPANDER_DIRECTION_IN ||
- direction == IOEXPANDER_DIRECTION_OUT));
+ if (direction != IOEXPANDER_DIRECTION_IN &&
+ direction != IOEXPANDER_DIRECTION_OUT)
+ {
+ return -EINVAL;
+ }
+
+ DEBUGASSERT(priv != NULL && priv->config != NULL && pin < 8);
gpioinfo("I2C addr=%02x pin=%u direction=%s\n",
priv->config->address, pin,
diff --git a/drivers/ioexpander/skeleton.c b/drivers/ioexpander/skeleton.c
index 7269482..90b7e0d 100644
--- a/drivers/ioexpander/skeleton.c
+++ b/drivers/ioexpander/skeleton.c
@@ -193,12 +193,16 @@ static int skel_direction(FAR struct ioexpander_dev_s *dev, uint8_t pin,
FAR struct skel_dev_s *priv = (FAR struct skel_dev_s *)dev;
int ret;
+ if (direction != IOEXPANDER_DIRECTION_IN &&
+ direction != IOEXPANDER_DIRECTION_OUT)
+ {
+ return -EINVAL;
+ }
+
gpioinfo("pin=%u direction=%s\n",
pin, (direction == IOEXPANDER_DIRECTION_IN) ? "IN" : "OUT");
- DEBUGASSERT(priv != NULL && pin < CONFIG_IOEXPANDER_NPINS &&
- (direction == IOEXPANDER_DIRECTION_IN ||
- direction == IOEXPANDER_DIRECTION_IN));
+ DEBUGASSERT(priv != NULL && pin < CONFIG_IOEXPANDER_NPINS);
/* Get exclusive access to the I/O Expander */
@@ -730,7 +734,9 @@ static void skel_interrupt(FAR void *arg)
/* Disable interrupts */
#warning Missing logic
- /* Schedule interrupt related work on the high priority worker thread. */
+ /* Schedule interrupt related work on the high priority worker
+ * thread.
+ */
work_queue(HPWORK, &priv->work, skel_irqworker,
(FAR void *)priv, 0);
diff --git a/drivers/ioexpander/tca64xx.c b/drivers/ioexpander/tca64xx.c
index 5de8763..215244a 100644
--- a/drivers/ioexpander/tca64xx.c
+++ b/drivers/ioexpander/tca64xx.c
@@ -419,10 +419,14 @@ static int tca64_direction(FAR struct ioexpander_dev_s *dev, uint8_t pin,
uint8_t regval;
int ret;
+ if (direction != IOEXPANDER_DIRECTION_IN &&
+ direction != IOEXPANDER_DIRECTION_OUT)
+ {
+ return -EINVAL;
+ }
+
DEBUGASSERT(priv != NULL && priv->config != NULL &&
- pin < CONFIG_IOEXPANDER_NPINS &&
- (direction == IOEXPANDER_DIRECTION_IN ||
- direction == IOEXPANDER_DIRECTION_OUT));
+ pin < CONFIG_IOEXPANDER_NPINS);
gpioinfo("I2C addr=%02x pin=%u direction=%s\n",
priv->config->address, pin,
diff --git a/include/nuttx/ioexpander/gpio.h b/include/nuttx/ioexpander/gpio.h
index 5d11e1c..f0a4661 100644
--- a/include/nuttx/ioexpander/gpio.h
+++ b/include/nuttx/ioexpander/gpio.h
@@ -100,8 +100,11 @@
enum gpio_pintype_e
{
- GPIO_INPUT_PIN = 0,
- GPIO_OUTPUT_PIN,
+ GPIO_INPUT_PIN = 0, /* float */
+ GPIO_INPUT_PIN_PULLUP,
+ GPIO_INPUT_PIN_PULLDOWN,
+ GPIO_OUTPUT_PIN, /* push-pull */
+ GPIO_OUTPUT_PIN_OPENDRAIN,
GPIO_INTERRUPT_PIN,
GPIO_INTERRUPT_HIGH_PIN,
GPIO_INTERRUPT_LOW_PIN,
@@ -141,7 +144,7 @@ struct gpio_operations_s
enum gpio_pintype_e pintype);
};
- /* Signal information */
+/* Signal information */
struct gpio_signal_s
{
diff --git a/include/nuttx/ioexpander/ioexpander.h b/include/nuttx/ioexpander/ioexpander.h
index f55aca9..e69bf8a 100644
--- a/include/nuttx/ioexpander/ioexpander.h
+++ b/include/nuttx/ioexpander/ioexpander.h
@@ -58,8 +58,11 @@
/* Pin definitions **********************************************************/
-#define IOEXPANDER_DIRECTION_IN 0
-#define IOEXPANDER_DIRECTION_OUT 1
+#define IOEXPANDER_DIRECTION_IN 0 /* float */
+#define IOEXPANDER_DIRECTION_IN_PULLUP 1
+#define IOEXPANDER_DIRECTION_IN_PULLDOWN 2
+#define IOEXPANDER_DIRECTION_OUT 3 /* push-pull */
+#define IOEXPANDER_DIRECTION_OUT_OPENDRAIN 4
#define IOEXPANDER_PINMASK (((ioe_pinset_t)1 << CONFIG_IOEXPANDER_NPINS) - 1)
#define PINSET_ALL (~((ioe_pinset_t)0))
@@ -144,14 +147,15 @@
* Name: IOEXP_READPIN
*
* Description:
- * Read the actual PIN level. This can be different from the last value written
- * to this pin. Required.
+ * Read the actual PIN level. This can be different from the last value
+ * written to this pin. Required.
*
* Input Parameters:
* dev - Device-specific state data
* pin - The index of the pin
* valptr - Pointer to a buffer where the pin level is stored. Usually TRUE
- * if the pin is high, except if OPTION_INVERT has been set on this pin.
+ * if the pin is high, except if OPTION_INVERT has been set on
+ * this pin.
*
* Returned Value:
* 0 on success, else a negative error code
@@ -225,8 +229,8 @@
* Name: IOEXP_MULTIREADBUF
*
* Description:
- * Read the buffered level of multiple pins. This routine may be faster than
- * individual pin accesses. Optional.
+ * Read the buffered level of multiple pins. This routine may be faster
+ * than individual pin accesses. Optional.
*
* Input Parameters:
* dev - Device-specific state data