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/06/07 14:26:40 UTC
[incubator-nuttx] branch master updated: arm/tlsr82: gpio driver bug fix and optimize.
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 af87921eda arm/tlsr82: gpio driver bug fix and optimize.
af87921eda is described below
commit af87921eda43728372b05a5b4bd6022cd1287b48
Author: wangbowen6 <wa...@xiaomi.com>
AuthorDate: Tue Jun 7 16:09:19 2022 +0800
arm/tlsr82: gpio driver bug fix and optimize.
Signed-off-by: wangbowen6 <wa...@xiaomi.com>
---
arch/arm/src/tlsr82/Kconfig | 8 ++
arch/arm/src/tlsr82/hardware/tlsr82_gpio.h | 2 +-
arch/arm/src/tlsr82/tlsr82_gpio.c | 139 +++++++++++++++++++--
arch/arm/src/tlsr82/tlsr82_gpio.h | 2 +-
.../arm/tlsr82/tlsr8278adk80d/src/tlsr8278_gpio.c | 126 ++++++++++++-------
5 files changed, 218 insertions(+), 59 deletions(-)
diff --git a/arch/arm/src/tlsr82/Kconfig b/arch/arm/src/tlsr82/Kconfig
index 8587ed74b5..d9d34918e0 100644
--- a/arch/arm/src/tlsr82/Kconfig
+++ b/arch/arm/src/tlsr82/Kconfig
@@ -209,6 +209,14 @@ config TLSR82_GPIO_VALIDATION
gpio can be configured be this multiplex function. But this function
need more flash space.
+config TLSR82_GPIO_DUMPREGS
+ bool "Tlsr82 gpio dump registers enable"
+ default n
+ depends on DEBUG_GPIO_INFO
+ ---help---
+ If enable this config, developer can call tlsr82_gpio_dumpregs() to
+ dump all the gpio registers.
+
endif
menuconfig TLSR82_I2C
diff --git a/arch/arm/src/tlsr82/hardware/tlsr82_gpio.h b/arch/arm/src/tlsr82/hardware/tlsr82_gpio.h
index d8ca83bca2..fa5241892c 100644
--- a/arch/arm/src/tlsr82/hardware/tlsr82_gpio.h
+++ b/arch/arm/src/tlsr82/hardware/tlsr82_gpio.h
@@ -90,7 +90,7 @@
#define GPIO_IRQ_NORMAL_ALL_REG REG_ADDR8(0x5b5)
#define GPIO_IRQ_RISC_EN_REG REG_ADDR8(0x642)
-#define GPIO_IRQ_NORMAL_REG(group) REG_ADDR8(0x587 + (group))
+#define GPIO_IRQ_NORMAL_REG(group) REG_ADDR8(0x587 + ((group) << 3))
#define GPIO_IRQ_M0_REG(group) REG_ADDR8(0x5b8 + (group))
#define GPIO_IRQ_M1_REG(group) REG_ADDR8(0x5c0 + (group))
#define GPIO_IRQ_M2_REG(group) REG_ADDR8(0x5c8 + (group))
diff --git a/arch/arm/src/tlsr82/tlsr82_gpio.c b/arch/arm/src/tlsr82/tlsr82_gpio.c
index 5bd0a5c158..31be903d30 100644
--- a/arch/arm/src/tlsr82/tlsr82_gpio.c
+++ b/arch/arm/src/tlsr82/tlsr82_gpio.c
@@ -69,6 +69,12 @@ struct tlsr82_gpio_irq_cb gpio_irq_cbs[CONFIG_GPIO_IRQ_MAX_NUM];
* Private Function Prototypes
****************************************************************************/
+#ifdef CONFIG_TLSR82_GPIO_DUMPREGS
+static void tlsr82_gpio_dumpregs(const char *msg);
+#else
+# define tlsr82_gpio_dumpregs(msg)
+#endif
+
static void tlsr82_gpio_ds_ctrl(gpio_cfg_t cfg, uint8_t ds);
static void tlsr82_gpio_pol_ctrl(gpio_cfg_t cfg, uint8_t pol);
@@ -76,6 +82,62 @@ static void tlsr82_gpio_pol_ctrl(gpio_cfg_t cfg, uint8_t pol);
* Private Functions
****************************************************************************/
+#ifdef CONFIG_TLSR82_GPIO_DUMPREGS
+static void tlsr82_gpio_dumpregs(const char *msg)
+{
+ int i = 0;
+ gpioinfo("%s\n", msg);
+ for (i = 0; i < 5; i++)
+ {
+ gpioinfo("Group %d Gpio Register:\n", i);
+ gpioinfo(" ACT=0x%02x\n", GPIO_SETTING_ACT_REG(i));
+ gpioinfo(" IN =0x%02x\n", GPIO_SETTING_IN_REG(i));
+
+ if (i != 3)
+ {
+ gpioinfo(" IE =0x%02x\n", GPIO_SETTING_IE_REG(i));
+ }
+ else
+ {
+ gpioinfo(" IE =0x%02x\n", tlsr82_analog_read(ANALOG_PC_IE_ADDR));
+ }
+
+ gpioinfo(" OEN=0x%02x\n", GPIO_SETTING_OEN_REG(i));
+ gpioinfo(" OUT=0x%02x\n", GPIO_SETTING_OUT_REG(i));
+ gpioinfo(" POL=0x%02x\n", GPIO_SETTING_POL_REG(i));
+
+ if (i != 3)
+ {
+ gpioinfo(" DS =0x%02x\n", GPIO_SETTING_DS_REG(i));
+ }
+ else
+ {
+ gpioinfo(" DS =0x%02x\n", tlsr82_analog_read(ANALOG_PC_DS_ADDR));
+ }
+ }
+
+ gpioinfo("Interrupt Register:\n");
+ for (i = 0; i < 5; i++)
+ {
+ gpioinfo(" IRQ NORMAL %d: 0x%02x\n", i, GPIO_IRQ_NORMAL_REG(i));
+ }
+
+ gpioinfo(" IRQ NORMAL ALL 0x%02x\n", GPIO_IRQ_NORMAL_ALL_REG);
+ gpioinfo(" IRQ RISC: 0x%02x\n", GPIO_IRQ_RISC_EN_REG);
+ gpioinfo(" IRQ MASK: 0x%08lx\n", IRQ_MASK_REG);
+
+ for (i = 0; i < CONFIG_GPIO_IRQ_MAX_NUM; i++)
+ {
+ gpioinfo("gpio_irq_cbs[%d]->arg : 0x%08x\n",
+ i, gpio_irq_cbs[i].arg);
+ gpioinfo("gpio_irq_cbs[%d]->callback: 0x%08x\n",
+ i, gpio_irq_cbs[i].callback);
+ gpioinfo("gpio_irq_cbs[%d]->cfg : 0x%08x\n",
+ i, gpio_irq_cbs[i].cfg);
+ }
+}
+#endif
+
/****************************************************************************
* Name: tlsr82_gpio_ds_ctrl
*
@@ -184,6 +246,8 @@ static int tlsr82_gpio_irq(int irq, void *context, void *arg)
xcpt_t callback;
int ret = OK;
+ gpioinfo("Gpio irq entry!\n");
+
/* Clear the GPIO interrupt status */
BM_SET(IRQ_SRC_REG, 1 << NR_GPIO_IRQ);
@@ -219,6 +283,8 @@ static int tlsr82_gpio_risc0_irq(int irq, void *context, void *arg)
xcpt_t callback;
int ret = OK;
+ gpioinfo("Gpio risc0 irq entry!\n");
+
/* Clear the GPIO interrupt status */
BM_SET(IRQ_SRC_REG, 1 << NR_GPIO_RISC0_IRQ);
@@ -254,6 +320,8 @@ static int tlsr82_gpio_risc1_irq(int irq, void *context, void *arg)
xcpt_t callback;
int ret = OK;
+ gpioinfo("Gpio risc1 irq entry!\n");
+
/* Clear the GPIO interrupt status */
BM_SET(IRQ_SRC_REG, 1 << NR_GPIO_RISC1_IRQ);
@@ -486,21 +554,17 @@ int tlsr82_gpioconfig(gpio_cfg_t cfg)
if (GPIO_IS(AF, INPUT, cfg))
{
- /* GPIO setting act as GPIO */
-
- BM_SET(GPIO_SETTING_ACT_REG(group), BIT(pin));
-
/* IE and OEN should be set to 1 for Input usage */
tlsr82_gpio_input_ctrl(cfg, true);
tlsr82_gpio_output_ctrl(cfg, false);
- }
- else if (GPIO_IS(AF, OUTPUT, cfg))
- {
+
/* GPIO setting act as GPIO */
BM_SET(GPIO_SETTING_ACT_REG(group), BIT(pin));
-
+ }
+ else if (GPIO_IS(AF, OUTPUT, cfg))
+ {
/* IE and OEN should be set to 0 for Output usage */
tlsr82_gpio_input_ctrl(cfg, false);
@@ -509,6 +573,10 @@ int tlsr82_gpioconfig(gpio_cfg_t cfg)
/* Drive Strength config */
tlsr82_gpio_ds_ctrl(cfg, (bool)GPIO_GET(DS, cfg));
+
+ /* GPIO setting act as GPIO */
+
+ BM_SET(GPIO_SETTING_ACT_REG(group), BIT(pin));
}
else if (GPIO_GET(AF, cfg) >= GPIO_VAL(AF, MUX0) &&
GPIO_GET(AF, cfg) <= GPIO_VAL(AF, MUX3))
@@ -667,6 +735,8 @@ void tlsr82_gpioirqinitialize(void)
* Description:
* Config the gpio irq according to the cfg, and attach or
* detach the interrupt callback function according to value of func.
+ * High Level or Rising Edge trigger, should set the pull-down resistor
+ * Low Level or Failing Edge trigger, should set the pull-up resistor
*
****************************************************************************/
@@ -676,6 +746,8 @@ int tlsr82_gpioirqconfig(gpio_cfg_t cfg, xcpt_t func, void *arg)
int i;
gpio_cfg_t pinset;
+ gpioinfo("cfg=0x%lx, func=0x%lx\n", cfg, (uint32_t)func);
+
/* Get pin information from cfg */
pinset = GPIO_CFG2PIN(cfg);
@@ -744,18 +816,26 @@ int tlsr82_gpioirqconfig(gpio_cfg_t cfg, xcpt_t func, void *arg)
tlsr82_gpioirqenable(cfg);
}
- /* GPIO must be in input mode for gpio interrupt */
+ /* Configure the gpio */
- tlsr82_gpioconfig(pinset | GPIO_AF_INPUT | GPIO_PUPD_NONE);
+ tlsr82_gpioconfig(cfg);
/* Config gpio interrupt polarity */
- tlsr82_gpio_pol_ctrl(GPIO_CFG2SDKPIN(cfg), GPIO_GET(POL, cfg));
+ tlsr82_gpio_pol_ctrl(cfg, GPIO_GET(POL, cfg));
+
+ /* Clear the interrupt flag */
+
+ tlsr82_gpioirqclear(cfg);
/* Enable corresponding gpio interrupt */
tlsr82_gpioirqenable_all();
+ /* Dump the gpio register for debug */
+
+ tlsr82_gpio_dumpregs("tlsr82_gpioirqconfig()");
+
return OK;
}
#endif
@@ -884,6 +964,43 @@ void tlsr82_gpioirqdisable(gpio_cfg_t cfg)
#endif
+/****************************************************************************
+ * Name: tlsr82_gpioirqclear
+ *
+ * Description:
+ * Clear the interrupt flag for specified GPIO IRQ
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_TLSR82_GPIO_IRQ
+void tlsr82_gpioirqclear(gpio_cfg_t cfg)
+{
+ uint32_t irqmode;
+
+ irqmode = (uint32_t)GPIO_GET(IRQ, cfg);
+
+ /* Clear corresponding gpio interrupt flag */
+
+ if (irqmode == GPIO_IRQ_NORMAL_VAL)
+ {
+ BM_SET(IRQ_SRC_REG, BIT(NR_GPIO_IRQ));
+ }
+ else if (irqmode == GPIO_IRQ_RISC0_VAL)
+ {
+ BM_SET(IRQ_SRC_REG, BIT(NR_GPIO_RISC0_IRQ));
+ }
+ else if (irqmode == GPIO_IRQ_RISC1_VAL)
+ {
+ BM_SET(IRQ_SRC_REG, BIT(NR_GPIO_RISC1_IRQ));
+ }
+ else
+ {
+ gpioerr("GPIO irq type is not correct, cfg=0x%lx\n", cfg);
+ }
+}
+
+#endif
+
/****************************************************************************
* Name: tlsr82_gpioirqdisable_all
*
diff --git a/arch/arm/src/tlsr82/tlsr82_gpio.h b/arch/arm/src/tlsr82/tlsr82_gpio.h
index 29859a23bf..e16f12c984 100644
--- a/arch/arm/src/tlsr82/tlsr82_gpio.h
+++ b/arch/arm/src/tlsr82/tlsr82_gpio.h
@@ -144,7 +144,7 @@
#define GPIO_POL_SHIFT 23
#define GPIO_POL_MASK (0x1 << GPIO_POL_SHIFT)
#define GPIO_POL_RISE (0 << GPIO_POL_SHIFT)
-#define GPIO_POL_FAIL (1 << GPIO_POL_SHIFT)
+#define GPIO_POL_FALL (1 << GPIO_POL_SHIFT)
/* GPIO specific pin definitions */
diff --git a/boards/arm/tlsr82/tlsr8278adk80d/src/tlsr8278_gpio.c b/boards/arm/tlsr82/tlsr8278adk80d/src/tlsr8278_gpio.c
index 484737faa2..8695eb1600 100644
--- a/boards/arm/tlsr82/tlsr8278adk80d/src/tlsr8278_gpio.c
+++ b/boards/arm/tlsr82/tlsr8278adk80d/src/tlsr8278_gpio.c
@@ -47,9 +47,11 @@
struct tlsr82gpio_dev_s
{
- struct gpio_dev_s gpio;
- pin_interrupt_t callback;
- uint8_t id;
+ struct gpio_dev_s gpio; /* GPIO Device */
+ pin_interrupt_t callback; /* Interrupt callback */
+ uint8_t id; /* ID */
+ gpio_cfg_t pinset; /* The pin set */
+ const enum gpio_pintype_e init_pintype; /* The pin type */
};
/****************************************************************************
@@ -78,24 +80,26 @@ static const struct gpio_operations_s gpio_ops =
.go_setpintype = tlsr82_go_setpintype,
};
-static gpio_cfg_t g_gpios[BOARD_NGPIO] =
+static struct tlsr82gpio_dev_s g_gpdevs[BOARD_NGPIO] =
{
- GPIO_PIN_PD6 | GPIO_AF_INPUT | GPIO_PUPD_NONE,
- GPIO_PIN_PD0 | GPIO_AF_OUTPUT | GPIO_PUPD_NONE,
- GPIO_PIN_PD1 | GPIO_AF_OUTPUT | GPIO_PUPD_NONE,
- GPIO_PIN_PB3 | GPIO_IRQ_NORMAL | GPIO_POL_RISE,
+ {
+ .pinset = GPIO_PIN_PD6,
+ .init_pintype = GPIO_INPUT_PIN_PULLDOWN,
+ },
+ {
+ .pinset = GPIO_PIN_PD0,
+ .init_pintype = GPIO_OUTPUT_PIN,
+ },
+ {
+ .pinset = GPIO_PIN_PD1,
+ .init_pintype = GPIO_OUTPUT_PIN,
+ },
+ {
+ .pinset = GPIO_PIN_PB3,
+ .init_pintype = GPIO_INTERRUPT_FALLING_PIN,
+ }
};
-static const enum gpio_pintype_e g_init_pintype[BOARD_NGPIO] =
-{
- GPIO_INPUT_PIN,
- GPIO_OUTPUT_PIN,
- GPIO_OUTPUT_PIN,
- GPIO_INTERRUPT_RISING_PIN,
-};
-
-static struct tlsr82gpio_dev_s g_gpdevs[BOARD_NGPIO];
-
/****************************************************************************
* Private Functions
****************************************************************************/
@@ -117,9 +121,9 @@ static int tlsr82_go_read(struct gpio_dev_s *dev, bool *value)
DEBUGASSERT(tlsr82gpio != NULL && value != NULL);
DEBUGASSERT(tlsr82gpio->id < BOARD_NGPIO);
- gpioinfo("Reading...\n");
+ gpioinfo("Reading, pinset=0x%08lx\n", tlsr82gpio->pinset);
- *value = tlsr82_gpioread(g_gpios[tlsr82gpio->id]);
+ *value = tlsr82_gpioread(tlsr82gpio->pinset);
return OK;
}
@@ -129,9 +133,9 @@ static int tlsr82_go_write(struct gpio_dev_s *dev, bool value)
DEBUGASSERT(tlsr82gpio != NULL);
DEBUGASSERT(tlsr82gpio->id < BOARD_NGPIO);
- gpioinfo("Writing %d\n", (int)value);
+ gpioinfo("Writing %d\n, pinset=0x%08lx\n", (int)value, tlsr82gpio->pinset);
- tlsr82_gpiowrite(g_gpios[tlsr82gpio->id], value);
+ tlsr82_gpiowrite(tlsr82gpio->pinset, value);
return OK;
}
@@ -144,7 +148,7 @@ static int tlsr82_go_attach(struct gpio_dev_s *dev,
/* Make sure the interrupt is disabled */
- tlsr82_gpioirqconfig(g_gpios[tlsr82gpio->id], NULL, NULL);
+ tlsr82_gpioirqconfig(tlsr82gpio->pinset, NULL, NULL);
gpioinfo("Attach %p\n", callback);
tlsr82gpio->callback = callback;
@@ -155,8 +159,6 @@ static int tlsr82_go_enable(struct gpio_dev_s *dev, bool enable)
{
struct tlsr82gpio_dev_s *tlsr82gpio = (struct tlsr82gpio_dev_s *)dev;
- uint8_t gpioid = tlsr82gpio->id;
-
if (enable)
{
if (tlsr82gpio->callback != NULL)
@@ -165,8 +167,8 @@ static int tlsr82_go_enable(struct gpio_dev_s *dev, bool enable)
/* Configure the interrupt for rising edge */
- tlsr82_gpioirqconfig(g_gpios[gpioid], tlsr82_go_interrupt,
- &g_gpdevs[gpioid]);
+ tlsr82_gpioirqconfig(tlsr82gpio->pinset, tlsr82_go_interrupt,
+ tlsr82gpio);
}
else
{
@@ -176,7 +178,7 @@ static int tlsr82_go_enable(struct gpio_dev_s *dev, bool enable)
else
{
gpioinfo("Disable the interrupt\n");
- tlsr82_gpioirqconfig(g_gpios[gpioid], NULL, NULL);
+ tlsr82_gpioirqconfig(tlsr82gpio->pinset, NULL, NULL);
}
return OK;
@@ -187,9 +189,11 @@ static int tlsr82_go_setpintype(struct gpio_dev_s *dev,
{
int ret = OK;
gpio_cfg_t cfg;
+ gpio_cfg_t irq;
struct tlsr82gpio_dev_s *tlsr82gpio = (struct tlsr82gpio_dev_s *)dev;
- cfg = GPIO_CFG2PIN(g_gpios[tlsr82gpio->id]);
+ cfg = GPIO_CFG2PIN(tlsr82gpio->pinset);
+ irq = tlsr82gpio->pinset & GPIO_IRQ_MASK;
switch (pintype)
{
@@ -216,31 +220,51 @@ static int tlsr82_go_setpintype(struct gpio_dev_s *dev,
case GPIO_OUTPUT_PIN:
{
- cfg = GPIO_AF_OUTPUT | GPIO_DS_HIGH;
+ cfg |= GPIO_AF_OUTPUT | GPIO_DS_HIGH;
tlsr82_gpioconfig(cfg);
}
break;
case GPIO_INTERRUPT_PIN:
+ case GPIO_INTERRUPT_HIGH_PIN:
case GPIO_INTERRUPT_RISING_PIN:
{
- cfg |= GPIO_AF_INPUT | GPIO_PUPD_NONE | GPIO_IRQ_NORMAL |
- GPIO_POL_RISE;
+ cfg |= GPIO_AF_INPUT | GPIO_PUPD_PD100K | GPIO_POL_RISE;
+ if (irq == GPIO_IRQ_DISABLE)
+ {
+ /* If do not specify the interrupt type, default normal */
+
+ cfg |= GPIO_IRQ_NORMAL;
+ }
+ else
+ {
+ cfg |= irq;
+ }
+
tlsr82_gpioirqconfig(cfg, NULL, NULL);
}
break;
+ case GPIO_INTERRUPT_LOW_PIN:
case GPIO_INTERRUPT_FALLING_PIN:
{
- cfg |= GPIO_AF_INPUT | GPIO_PUPD_NONE | GPIO_IRQ_NORMAL |
- GPIO_POL_FAIL;
+ cfg |= GPIO_AF_INPUT | GPIO_PUPD_PU10K | GPIO_POL_FALL;
+ if (irq == GPIO_IRQ_DISABLE)
+ {
+ /* If do not specify the interrupt type, default normal */
+
+ cfg |= GPIO_IRQ_NORMAL;
+ }
+ else
+ {
+ cfg |= irq;
+ }
+
tlsr82_gpioirqconfig(cfg, NULL, NULL);
}
break;
case GPIO_OUTPUT_PIN_OPENDRAIN:
- case GPIO_INTERRUPT_HIGH_PIN:
- case GPIO_INTERRUPT_LOW_PIN:
case GPIO_INTERRUPT_BOTH_PIN:
default:
{
@@ -252,7 +276,9 @@ static int tlsr82_go_setpintype(struct gpio_dev_s *dev,
/* Assign back the config information */
- g_gpios[tlsr82gpio->id] = cfg;
+ tlsr82gpio->pinset = cfg;
+
+ gpioinfo("pinset=0x%08lx\n", cfg);
errout:
return ret;
@@ -269,22 +295,30 @@ errout:
int tlsr82_gpio_initialize(void)
{
int i;
+ int ret = OK;
+ struct tlsr82gpio_dev_s *tlsr82gpio;
- tlsr82_gpioirqconfig(g_gpios[3], NULL, NULL);
+ tlsr82_gpioirqinitialize();
for (i = 0; i < BOARD_NGPIO; i++)
{
- g_gpdevs[i].gpio.gp_pintype = g_init_pintype[i];
- g_gpdevs[i].gpio.gp_ops = &gpio_ops;
- g_gpdevs[i].id = i;
- gpio_pin_register(&g_gpdevs[i].gpio, i);
-
- /* Configure the pin that will be used as input */
+ tlsr82gpio = &g_gpdevs[i];
+ tlsr82gpio->gpio.gp_pintype = tlsr82gpio->init_pintype;
+ tlsr82gpio->gpio.gp_ops = &gpio_ops;
+ tlsr82gpio->id = i;
+
+ ret = tlsr82_go_setpintype(&tlsr82gpio->gpio,
+ tlsr82gpio->init_pintype);
+ if (ret < 0)
+ {
+ goto out;
+ }
- tlsr82_gpioconfig(g_gpios[i]);
+ gpio_pin_register(&tlsr82gpio->gpio, i);
}
- return 0;
+out:
+ return ret;
}
#endif /* CONFIG_DEV_GPIO && !CONFIG_GPIO_LOWER_HALF */