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:
chenzihan1
2024-12-31 15:49:18 +08:00
committed by Michal Lenc
parent b09d402d06
commit a9df67e56b
5 changed files with 126 additions and 8 deletions
@@ -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
~~~~~~~~~~~~~~~~~~~
+28
View File
@@ -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:
+43
View File
@@ -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
*
+23 -6
View File
@@ -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 */
+2
View File
@@ -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 ************************************************************/