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/nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new c63b0510fb4 rp23xx/rp23xx-rv: Fix GPIO interrupt handler for RP2350B 
variant.
c63b0510fb4 is described below

commit c63b0510fb4f922638d7537ce8f1a0baf4e24a40
Author: paolo <[email protected]>
AuthorDate: Fri Jan 30 14:05:33 2026 +0100

    rp23xx/rp23xx-rv: Fix GPIO interrupt handler for RP2350B variant.
    
    The GPIO interrupt handler had hardcoded values that only worked
    correctly for RP2350A (30 GPIOs). For RP2350B (48 GPIOs):
    
    - Loop count was hardcoded to 6 registers but should be computed
      based on RP23XX_GPIO_NUM (4 for RP2350A, 6 for RP2350B)
    - Reserved bits mask was always applied at register index 3, but
      for RP2350B register 3 contains valid GPIOs 24-31. This caused
      interrupts for GPIOs 30-31 to be incorrectly discarded
    - PWM port validation rejected valid ports 8-11 on RP2350B which
      has 12 PWM slices instead of 8
    
    Changes:
    - Add RP23XX_GPIO_NREGS macro to compute number of interrupt registers
    - Use conditional compilation to only mask reserved bits on RP2350A
      where the last register has 6 valid GPIOs (bits 0-23)
    - Fix PWM port validation to allow 12 ports on RP2350B
    
    Signed-off-by: paolo <[email protected]>
---
 arch/arm/src/rp23xx/rp23xx_gpio.c       | 18 +++++++++++++++---
 arch/arm/src/rp23xx/rp23xx_gpio.h       |  4 ++++
 arch/risc-v/src/rp23xx-rv/rp23xx_gpio.c | 18 +++++++++++++++---
 arch/risc-v/src/rp23xx-rv/rp23xx_gpio.h |  4 ++++
 4 files changed, 38 insertions(+), 6 deletions(-)

diff --git a/arch/arm/src/rp23xx/rp23xx_gpio.c 
b/arch/arm/src/rp23xx/rp23xx_gpio.c
index 64b9e554bff..0c15a3edb11 100644
--- a/arch/arm/src/rp23xx/rp23xx_gpio.c
+++ b/arch/arm/src/rp23xx/rp23xx_gpio.c
@@ -168,15 +168,23 @@ static int rp23xx_gpio_interrupt(int irq, void *context, 
void *arg)
 
   /* Scan all GPIO interrupt status registers */
 
-  for (i = 0; i < 6; i++)
+  for (i = 0; i < RP23XX_GPIO_NREGS; i++)
     {
       /* Get and clear pending GPIO interrupt status */
 
       stat = getreg32(RP23XX_IO_BANK0_PROC_INTS(i * 8, 0));
-      if (i == 3)
+
+#if (RP23XX_GPIO_NUM & 7) != 0
+      /* Mask reserved bits in the last register.
+       * RP2350A: 30 GPIOs, last register has 6 valid GPIOs (bits 0-23)
+       * RP2350B: 48 GPIOs, all registers fully used (no masking needed)
+       */
+
+      if (i == RP23XX_GPIO_NREGS - 1)
         {
-          stat &= 0x00ffffff;     /* Clear reserved bits */
+          stat &= (1u << ((RP23XX_GPIO_NUM & 7) * 4)) - 1;
         }
+#endif
 
       putreg32(stat, RP23XX_IO_BANK0_INTR(i * 8));
 
@@ -256,7 +264,11 @@ int rp23xx_gpio_get_function_pin(uint32_t func, uint32_t 
port)
         break;
 
       case RP23XX_GPIO_FUNC_PWM:
+#ifdef CONFIG_RP23XX_RP2350B
+        if (port >= 12)
+#else
         if (port >= 8)
+#endif
           {
             return -1;
           }
diff --git a/arch/arm/src/rp23xx/rp23xx_gpio.h 
b/arch/arm/src/rp23xx/rp23xx_gpio.h
index 5eaa6d0b266..ea94cac14a1 100644
--- a/arch/arm/src/rp23xx/rp23xx_gpio.h
+++ b/arch/arm/src/rp23xx/rp23xx_gpio.h
@@ -48,6 +48,10 @@
 #define RP23XX_GPIO_NUM    30       /* Number of GPIO pins */
 #endif
 
+/* Number of GPIO interrupt status registers */
+
+#define RP23XX_GPIO_NREGS  ((RP23XX_GPIO_NUM + 7) / 8)
+
 /* GPIO function types ******************************************************/
 
 #define RP23XX_GPIO_FUNC_HSTX       RP23XX_IO_BANK0_GPIO_CTRL_FUNCSEL_HSTX
diff --git a/arch/risc-v/src/rp23xx-rv/rp23xx_gpio.c 
b/arch/risc-v/src/rp23xx-rv/rp23xx_gpio.c
index 46148db5fe4..361ecf66a73 100644
--- a/arch/risc-v/src/rp23xx-rv/rp23xx_gpio.c
+++ b/arch/risc-v/src/rp23xx-rv/rp23xx_gpio.c
@@ -168,15 +168,23 @@ static int rp23xx_gpio_interrupt(int irq, void *context, 
void *arg)
 
   /* Scan all GPIO interrupt status registers */
 
-  for (i = 0; i < 6; i++)
+  for (i = 0; i < RP23XX_GPIO_NREGS; i++)
     {
       /* Get and clear pending GPIO interrupt status */
 
       stat = getreg32(RP23XX_IO_BANK0_PROC_INTS(i * 8, 0));
-      if (i == 3)
+
+#if (RP23XX_GPIO_NUM & 7) != 0
+      /* Mask reserved bits in the last register.
+       * RP2350A: 30 GPIOs, last register has 6 valid GPIOs (bits 0-23)
+       * RP2350B: 48 GPIOs, all registers fully used (no masking needed)
+       */
+
+      if (i == RP23XX_GPIO_NREGS - 1)
         {
-          stat &= 0x00ffffff;     /* Clear reserved bits */
+          stat &= (1u << ((RP23XX_GPIO_NUM & 7) * 4)) - 1;
         }
+#endif
 
       putreg32(stat, RP23XX_IO_BANK0_INTR(i * 8));
 
@@ -256,7 +264,11 @@ int rp23xx_gpio_get_function_pin(uint32_t func, uint32_t 
port)
         break;
 
       case RP23XX_GPIO_FUNC_PWM:
+#ifdef CONFIG_RP23XX_RV_RP2350B
+        if (port >= 12)
+#else
         if (port >= 8)
+#endif
           {
             return -1;
           }
diff --git a/arch/risc-v/src/rp23xx-rv/rp23xx_gpio.h 
b/arch/risc-v/src/rp23xx-rv/rp23xx_gpio.h
index 98aabda43e1..25cae2ddab6 100644
--- a/arch/risc-v/src/rp23xx-rv/rp23xx_gpio.h
+++ b/arch/risc-v/src/rp23xx-rv/rp23xx_gpio.h
@@ -48,6 +48,10 @@
 #define RP23XX_GPIO_NUM    30       /* Number of GPIO pins */
 #endif
 
+/* Number of GPIO interrupt status registers */
+
+#define RP23XX_GPIO_NREGS  ((RP23XX_GPIO_NUM + 7) / 8)
+
 /* GPIO function types ******************************************************/
 
 #define RP23XX_GPIO_FUNC_HSTX       RP23XX_IO_BANK0_GPIO_CTRL_FUNCSEL_HSTX

Reply via email to