From af87921eda43728372b05a5b4bd6022cd1287b48 Mon Sep 17 00:00:00 2001 From: wangbowen6 Date: Tue, 7 Jun 2022 16:09:19 +0800 Subject: [PATCH] arm/tlsr82: gpio driver bug fix and optimize. Signed-off-by: wangbowen6 --- 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 +- .../tlsr82/tlsr8278adk80d/src/tlsr8278_gpio.c | 124 ++++++++++------ 5 files changed, 217 insertions(+), 58 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); + tlsr82gpio = &g_gpdevs[i]; + tlsr82gpio->gpio.gp_pintype = tlsr82gpio->init_pintype; + tlsr82gpio->gpio.gp_ops = &gpio_ops; + tlsr82gpio->id = i; - /* Configure the pin that will be used as input */ + 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 */