mirror of
https://github.com/apache/nuttx.git
synced 2026-05-22 05:42:05 +08:00
drivers/gpio: gpio driver added debounce and interrupt mask functions
Add handling for GPIOC_SETDEBOUNCE to set GPIO pin debounce duration. Add handling for GPIOC_SETMASK to enable/disable GPIO interrupt mask. Signed-off-by: chenzihan1 <chenzihan1@xiaomi.com>
This commit is contained in:
@@ -44,6 +44,8 @@ are supported:
|
||||
* :c:macro:`GPIOC_REGISTER`
|
||||
* :c:macro:`GPIOC_UNREGISTER`
|
||||
* :c:macro:`GPIOC_SETPINTYPE`
|
||||
* :c:macro:`GPIOC_SETDEBOUNCE`
|
||||
* :c:macro:`GPIOC_IRQ_SETMASK`
|
||||
|
||||
|
||||
.. c:macro:: GPIOC_WRITE
|
||||
@@ -104,8 +106,8 @@ is a pointer to an instance of type :c:enum:`gpio_pintype_e`.
|
||||
|
||||
The ``GPIOC_REGISTER`` command registers a pin to receive a signal whenever
|
||||
there is an interrupt received on an input GPIO pin. This feature, of course,
|
||||
depends upon interript GPIO support in the platform specific code. Please
|
||||
refer to the documentation describing your target platform for futher
|
||||
depends upon interrupt GPIO support in the platform specific code. Please
|
||||
refer to the documentation describing your target platform for further
|
||||
information. The argument is the pointer to :c:type:`sigevent` value, a signal
|
||||
to be generated when the interrupt occurs.
|
||||
|
||||
@@ -131,6 +133,32 @@ The ``GPIOC_SETPINTYPE`` command can be used to change the GPIO pin type
|
||||
(from input pin to output pin, changing interrupt edges and similar). The
|
||||
types to set are listed in :c:enum:`gpio_pintype_e`.
|
||||
|
||||
.. c:macro:: GPIOC_SETDEBOUNCE
|
||||
|
||||
The ``GPIOC_SETDEBOUNCE`` command sets the debounce time for a GPIO input pin.
|
||||
The argument is a pointer to an integer value, which specifies the debounce time in milliseconds.
|
||||
This helps to filter out spurious transitions (noise) on the input pin.
|
||||
|
||||
Typical use case:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
int debounce_ms = 10;
|
||||
int ret = ioctl(fd, GPIOC_SETDEBOUNCE, (unsigned long)(uintptr_t)&debounce_ms);
|
||||
|
||||
.. c:macro:: GPIOC_IRQ_SETMASK
|
||||
|
||||
The ``GPIOC_IRQ_SETMASK`` command sets the interrupt mask for a GPIO pin.
|
||||
The argument is a pointer to an integer value, which specifies the mask to enable or disable specific interrupt types (such as rising/falling edge, level, etc).
|
||||
The exact meaning of the mask depends on the platform implementation.
|
||||
|
||||
Typical use case:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
int irq_mask = /* platform-specific mask value */;
|
||||
int ret = ioctl(fd, GPIOC_IRQ_SETMASK, (unsigned long)(uintptr_t)&irq_mask);
|
||||
|
||||
Application Example
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
||||
@@ -576,6 +576,34 @@ static int gpio_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
||||
}
|
||||
break;
|
||||
|
||||
/* Command: GPIOC_SETDEBOUNCE
|
||||
* Description: Set the GPIO pin debounce duration.
|
||||
* Argument: The duration of the channel debounce, uint is ns.
|
||||
*/
|
||||
|
||||
case GPIOC_SETDEBOUNCE:
|
||||
{
|
||||
DEBUGASSERT(dev->gp_ops->go_setdebounce != NULL);
|
||||
ret = dev->gp_ops->go_setdebounce(dev, arg);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Command: GPIOC_SETMASK
|
||||
* Description: Mask or unmask the GPIO interrupt without disabling it.
|
||||
* When masked, the interrupt is suppressed but the
|
||||
* interrupt source remains enabled.
|
||||
* Argument: true to mask the interrupt;
|
||||
* false to unmask the interrupt.
|
||||
*/
|
||||
|
||||
case GPIOC_IRQ_SETMASK:
|
||||
{
|
||||
bool mask = (bool)arg;
|
||||
DEBUGASSERT(dev->gp_ops->go_setmask != NULL);
|
||||
ret = dev->gp_ops->go_setmask(dev, mask);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Unrecognized command */
|
||||
|
||||
default:
|
||||
|
||||
@@ -79,6 +79,10 @@ static int gplh_enable(FAR struct gpio_dev_s *gpio, bool enable);
|
||||
#endif
|
||||
static int gplh_setpintype(FAR struct gpio_dev_s *gpio,
|
||||
enum gpio_pintype_e pintype);
|
||||
static int gplh_setdebounce(FAR struct gpio_dev_s *gpio,
|
||||
unsigned long duration);
|
||||
static int gplh_setmask(FAR struct gpio_dev_s *gpio,
|
||||
bool mask);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
@@ -98,6 +102,8 @@ static const struct gpio_operations_s g_gplh_ops =
|
||||
NULL, /* enable */
|
||||
#endif
|
||||
gplh_setpintype,
|
||||
gplh_setdebounce,
|
||||
gplh_setmask,
|
||||
};
|
||||
|
||||
/* Identifies the type of the GPIO pin */
|
||||
@@ -395,6 +401,43 @@ static int gplh_setpintype(FAR struct gpio_dev_s *gpio,
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: gplh_setdebounce
|
||||
*
|
||||
* Description:
|
||||
* Set I/O expander debounce duration, unit is ns.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int gplh_setdebounce(FAR struct gpio_dev_s *gpio,
|
||||
unsigned long duration)
|
||||
{
|
||||
FAR struct gplh_dev_s *priv = (FAR struct gplh_dev_s *)gpio;
|
||||
FAR struct ioexpander_dev_s *ioe = priv->ioe;
|
||||
uint8_t pin = priv->pin;
|
||||
IOEXP_SETOPTION(ioe, pin, IOEXPANDER_OPTION_SETDEBOUNCE,
|
||||
(FAR void *)duration);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: gplh_setmask
|
||||
*
|
||||
* Description:
|
||||
* Set I/O expander whether to enable interrupt mask
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int gplh_setmask(FAR struct gpio_dev_s *gpio,
|
||||
bool mask)
|
||||
{
|
||||
FAR struct gplh_dev_s *priv = (FAR struct gplh_dev_s *)gpio;
|
||||
FAR struct ioexpander_dev_s *ioe = priv->ioe;
|
||||
uint8_t pin = priv->pin;
|
||||
IOEXP_SETOPTION(ioe, pin, IOEXPANDER_OPTION_SETMASK, (FAR void *)mask);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: gpio_lower_half_internal
|
||||
*
|
||||
|
||||
@@ -70,14 +70,26 @@
|
||||
* Description: Set the GPIO pin type.
|
||||
* Argument: The enum gpio_pintype_e type.
|
||||
*
|
||||
* Command: GPIOC_SETDEBOUNCE
|
||||
* Description: Set the channel debounce duration
|
||||
* Argument: The duration of the channel debounce, unit is ns.
|
||||
|
||||
* Command: GPIOC_IRQ_SETMASK
|
||||
* Description: Mask or unmask the GPIO interrupt without disabling it.
|
||||
* When masked, the interrupt is suppressed but the
|
||||
* interrupt source remains enabled.
|
||||
* Argument: true to mask the interrupt;
|
||||
* false to unmask the interrupt.
|
||||
*/
|
||||
|
||||
#define GPIOC_WRITE _GPIOC(1)
|
||||
#define GPIOC_READ _GPIOC(2)
|
||||
#define GPIOC_PINTYPE _GPIOC(3)
|
||||
#define GPIOC_REGISTER _GPIOC(4)
|
||||
#define GPIOC_UNREGISTER _GPIOC(5)
|
||||
#define GPIOC_SETPINTYPE _GPIOC(6)
|
||||
#define GPIOC_WRITE _GPIOC(1)
|
||||
#define GPIOC_READ _GPIOC(2)
|
||||
#define GPIOC_PINTYPE _GPIOC(3)
|
||||
#define GPIOC_REGISTER _GPIOC(4)
|
||||
#define GPIOC_UNREGISTER _GPIOC(5)
|
||||
#define GPIOC_SETPINTYPE _GPIOC(6)
|
||||
#define GPIOC_SETDEBOUNCE _GPIOC(7)
|
||||
#define GPIOC_IRQ_SETMASK _GPIOC(8)
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
@@ -125,6 +137,8 @@ typedef CODE int (*pin_interrupt_t)(FAR struct gpio_dev_s *dev, uint8_t pin);
|
||||
* - go_attach and go_enable. Required only for the GPIO_INTERRUPT_PIN pin
|
||||
* type. Unused for other pin types, may be NULL.
|
||||
* - go_setpintype. Required for all pin types.
|
||||
* - go_setdebounce. Required for all pin types.
|
||||
* - go_setmask. Required only for the GPIO_INTERRUPT_PIN pin
|
||||
*/
|
||||
|
||||
struct gpio_dev_s;
|
||||
@@ -139,6 +153,9 @@ struct gpio_operations_s
|
||||
CODE int (*go_enable)(FAR struct gpio_dev_s *dev, bool enable);
|
||||
CODE int (*go_setpintype)(FAR struct gpio_dev_s *dev,
|
||||
enum gpio_pintype_e pintype);
|
||||
CODE int (*go_setdebounce)(FAR struct gpio_dev_s *gpio,
|
||||
unsigned long duration);
|
||||
CODE int (*go_setmask)(FAR struct gpio_dev_s *dev, bool enable);
|
||||
};
|
||||
|
||||
/* Signal information */
|
||||
|
||||
@@ -82,6 +82,8 @@
|
||||
#define IOEXPANDER_OPTION_WAKEUPCFG 5 /* Configure interrupt for a pin to wake up the Soc */
|
||||
#define IOEXPANDER_WAKEUP_DISABLE 0 /* Do not cfg the pin as wake up source */
|
||||
#define IOEXPANDER_WAKEUP_ENABLE 1 /* Cfg the pin as wake up source */
|
||||
#define IOEXPANDER_OPTION_SETDEBOUNCE 6 /* Configure debounce duration */
|
||||
#define IOEXPANDER_OPTION_SETMASK 7 /* Mask the interrupter */
|
||||
|
||||
/* Access macros ************************************************************/
|
||||
|
||||
|
||||
Reference in New Issue
Block a user