You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by "g2gps (via GitHub)" <gi...@apache.org> on 2023/01/31 01:37:54 UTC

[GitHub] [nuttx] g2gps opened a new pull request, #8368: litex: Add GPIO driver.

g2gps opened a new pull request, #8368:
URL: https://github.com/apache/nuttx/pull/8368

   ## Summary
   GPIO driver for Litex with optional ISR support. Allows for multiple GPIO peripherals to be specified at an arbitrary addresses. Supports only push / pull output or input.
   
   Each peripheral can contain up to 32 signals, each with its own 'second level' dispatched IRQ.
   
   ## Impact
   
   Add Kconfig options for GPIO driver and GPIO IRQ selection. GPIO driver is only added to build when selected. 
   
   `LITEX_GPIO_BASE`, `LITEX_GPIO_OFFSET`, and `LITEX_GPIO_MAX`, are set to values which work. However, they can be overridden using custom definitions (see #8233)  to suit gateware. 
    
   
   ## Testing
   
   Testing conducted on our development board, with a peripheral built-in to gateware. I've tested:
    - GPIO write, high and low signals.
    - GPIO read, high and low signals
    - GPIO interrupts on rising edge, falling edge and both edges.
   
   on various pins over a single port. 


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] xiaoxiang781216 commented on a diff in pull request #8368: litex: Add GPIO driver.

Posted by "xiaoxiang781216 (via GitHub)" <gi...@apache.org>.
xiaoxiang781216 commented on code in PR #8368:
URL: https://github.com/apache/nuttx/pull/8368#discussion_r1091483501


##########
arch/risc-v/src/litex/hardware/litex_memorymap.h:
##########
@@ -50,6 +50,20 @@
 #define LITEX_TIMER0_BASE       0xf0006000
 #define LITEX_UART0_BASE        0xf0006800
 
+/* GPIO peripheral definitions.
+ *  - LITEX_GPIO_BASE is the first 32-bit address which contains a block
+ *    of GPIO registers (peripheral). Each block can contain up to 32 pins.
+ *  - LITEX_GPIO_OFFSET is the number of bytes between each GPIO peripheral.
+ *  - LITEX_GPIO_MAX is the number of peripherals enabled in gateware.
+ *
+ *  Each peripheral is referenced by an index in the GPIO driver. E.g Index 0
+ *  is the first GPIO peripheral at 0xF0008000. Index 1 is at 0xF00080020.
+ */
+
+#define LITEX_GPIO_BASE         0xF0008000

Review Comment:
   ```suggestion
   #define LITEX_GPIO_BASE         0xf0008000
   ```



##########
arch/risc-v/src/litex/litex_gpio.c:
##########
@@ -0,0 +1,357 @@
+/****************************************************************************
+ * arch/risc-v/src/litex/litex_gpio.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <assert.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <arch/irq.h>
+
+#include "riscv_internal.h"
+#include "litex_gpio.h"
+#include "litex_memorymap.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define GPIO_REG_OE_OFFSET          0x00
+#define GPIO_REG_IN_OFFSET          0x04
+#define GPIO_REG_OUT_OFFSET         0x08
+#define GPIO_REG_MODE_OFFSET        0x0C
+#define GPIO_REG_EDGE_OFFSET        0x10
+#define GPIO_REG_EV_STATUS_OFFSET   0x14
+#define GPIO_REG_EV_PEND_OFFSET     0x18
+#define GPIO_REG_EV_ENABLE_OFFSET   0x1C
+
+#ifdef CONFIG_LITEX_GPIO_IRQ
+/* Helper to calculate the GPIO port index from an IRQ number. */
+#define irq_to_gpio_index(_irqno) (( _irqno - LITEX_IRQ_GPIO) % 32)
+
+/* Helper to calculate the extended IRQ number from GPIO  port index. */
+#define gpio_index_to_irq(_i, _p) ((_i * 32) + _p + LITEX_FIRST_GPIOIRQ)
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions Prototypes
+ ****************************************************************************/
+
+static uint32_t gpiobase_at(uint32_t index);
+
+#ifdef CONFIG_LITEX_GPIO_IRQ
+static void gpio_dispatch(int irq, uint32_t gpiobase, uint32_t * regs);
+static int litex_gpio_interrupt(int irq, void *context, void * arg);
+#endif
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* A lookup table to keep track of all the base addresses for all gateware
+ * defined GPIO peripherals. This saves calculating the actual base address
+ * in the ISR routines, as there is only an IRQ number available at that
+ * point.
+ *
+ * The actual memory addresses are populated the first time it is used.
+ */
+
+static uint32_t gpio_base_s[LITEX_GPIO_MAX] =
+{
+  0
+};
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static uint32_t gpiobase_at(uint32_t index)
+{
+  DEBUGASSERT(index < LITEX_GPIO_MAX);
+  if (gpio_base_s[0] == 0)
+    {
+      for (int i = 0; i < LITEX_GPIO_MAX; i++)
+        {
+          gpio_base_s[i] = LITEX_GPIO_BASE +
+                          (LITEX_GPIO_OFFSET * i);
+        }
+    }
+
+  return gpio_base_s[index];
+}
+
+#ifdef CONFIG_LITEX_GPIO_IRQ
+static void gpio_dispatch(int irq, uint32_t gpiobase, uint32_t * regs)
+{
+  int i;
+  int ndx = 0;
+  uint32_t bitmask;
+
+  /* Query which pin interrupts are enabled */
+
+  uint32_t enabled = getreg32(gpiobase + GPIO_REG_EV_ENABLE_OFFSET);
+
+  /* Query which interrupts are pending */
+
+  uint32_t pending = getreg32(gpiobase + GPIO_REG_EV_PEND_OFFSET);
+
+  while ((i = __builtin_ffs(pending)))

Review Comment:
   ffs?



##########
arch/risc-v/src/litex/litex_gpio.c:
##########
@@ -0,0 +1,357 @@
+/****************************************************************************
+ * arch/risc-v/src/litex/litex_gpio.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <assert.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <arch/irq.h>
+
+#include "riscv_internal.h"
+#include "litex_gpio.h"
+#include "litex_memorymap.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define GPIO_REG_OE_OFFSET          0x00
+#define GPIO_REG_IN_OFFSET          0x04
+#define GPIO_REG_OUT_OFFSET         0x08
+#define GPIO_REG_MODE_OFFSET        0x0C
+#define GPIO_REG_EDGE_OFFSET        0x10
+#define GPIO_REG_EV_STATUS_OFFSET   0x14
+#define GPIO_REG_EV_PEND_OFFSET     0x18
+#define GPIO_REG_EV_ENABLE_OFFSET   0x1C
+
+#ifdef CONFIG_LITEX_GPIO_IRQ
+/* Helper to calculate the GPIO port index from an IRQ number. */
+#define irq_to_gpio_index(_irqno) (( _irqno - LITEX_IRQ_GPIO) % 32)
+
+/* Helper to calculate the extended IRQ number from GPIO  port index. */
+#define gpio_index_to_irq(_i, _p) ((_i * 32) + _p + LITEX_FIRST_GPIOIRQ)
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions Prototypes
+ ****************************************************************************/
+
+static uint32_t gpiobase_at(uint32_t index);
+
+#ifdef CONFIG_LITEX_GPIO_IRQ
+static void gpio_dispatch(int irq, uint32_t gpiobase, uint32_t * regs);
+static int litex_gpio_interrupt(int irq, void *context, void * arg);
+#endif
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* A lookup table to keep track of all the base addresses for all gateware
+ * defined GPIO peripherals. This saves calculating the actual base address
+ * in the ISR routines, as there is only an IRQ number available at that
+ * point.
+ *
+ * The actual memory addresses are populated the first time it is used.
+ */
+
+static uint32_t gpio_base_s[LITEX_GPIO_MAX] =
+{
+  0
+};
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static uint32_t gpiobase_at(uint32_t index)
+{
+  DEBUGASSERT(index < LITEX_GPIO_MAX);
+  if (gpio_base_s[0] == 0)
+    {
+      for (int i = 0; i < LITEX_GPIO_MAX; i++)
+        {
+          gpio_base_s[i] = LITEX_GPIO_BASE +
+                          (LITEX_GPIO_OFFSET * i);
+        }
+    }
+
+  return gpio_base_s[index];
+}
+
+#ifdef CONFIG_LITEX_GPIO_IRQ
+static void gpio_dispatch(int irq, uint32_t gpiobase, uint32_t * regs)
+{
+  int i;
+  int ndx = 0;
+  uint32_t bitmask;
+
+  /* Query which pin interrupts are enabled */
+
+  uint32_t enabled = getreg32(gpiobase + GPIO_REG_EV_ENABLE_OFFSET);
+
+  /* Query which interrupts are pending */
+
+  uint32_t pending = getreg32(gpiobase + GPIO_REG_EV_PEND_OFFSET);
+
+  while ((i = __builtin_ffs(pending)))
+    {
+      ndx += i;
+      bitmask = 0x1 << (ndx - 1);
+
+      /* Clear the pending interrupt */
+
+      modifyreg32(gpiobase + GPIO_REG_EV_PEND_OFFSET, bitmask, bitmask);
+
+      /* Dispatch the appropriate interrupt handler if the ISR is enabled. */
+
+      if (enabled & bitmask)
+        {
+          irq_dispatch(irq + ndx - 1, regs);
+        }
+
+      pending >>= i;
+    }
+}
+#endif
+
+#ifdef CONFIG_LITEX_GPIO_IRQ
+static int litex_gpio_interrupt(int irq, void * context, void * arg)
+{
+  uint32_t gpiobase = 0;
+  uint32_t gpioindex = irq_to_gpio_index(irq);
+
+  DEBUGASSERT(gpioindex < LITEX_GPIO_MAX);
+
+  gpiobase = gpiobase_at(gpioindex);
+
+  gpio_dispatch(LITEX_FIRST_GPIOIRQ, gpiobase, (uint32_t *)context);
+  return OK;
+}
+#endif
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: litex_gpio_config
+ *
+ * Description:
+ *   Configure a GPIO pin based on encoded pin attributes. GPIO's currently
+ *   only support a single attribute.
+ *
+ * Input Parameters:
+ *   port      - The GPIO port number to read from.
+ *   pin       - The pin, or bit offset inside the GPIO port.
+ *   attr      - The pin attribute to apply to the pin.
+ *
+ * Returned Value:
+ *   Zero (OK) is returned on success; a negated errno value is returned
+ *   on failure.
+ *
+ ****************************************************************************/
+
+int litex_gpio_config(uint32_t port, uint32_t pin, gpio_pinattr_t attr)
+{
+  int ret = OK;
+  int bitmask = 0x1 << pin;
+  switch (attr)
+  {
+     case GPIO_PINMODE_INPUT:
+      modifyreg32(gpiobase_at(port) + GPIO_REG_OE_OFFSET, bitmask, 0);
+      break;
+    case GPIO_PINMODE_OUTPUT:
+      modifyreg32(gpiobase_at(port) + GPIO_REG_OE_OFFSET, bitmask, bitmask);
+      break;
+    default:
+      ret = -ENODEV;
+      break;
+  }
+
+  return ret;
+}
+
+/****************************************************************************
+ * Name: litex_gpio_write
+ *
+ * Description:
+ *   Write one or zero to the selected GPIO pin.
+ *
+ * Input Parameters:
+ *   port      - The GPIO port number to read from.
+ *   pin       - The pin, or bit offset inside the GPIO port.
+ *
+ ****************************************************************************/
+
+void litex_gpio_write(uint32_t port, uint32_t pin, bool value)
+{
+    modifyreg32(gpiobase_at(port) + GPIO_REG_OUT_OFFSET, 0x1 << pin,
+                                              (uint32_t)value << pin);
+}
+
+/****************************************************************************
+ * Name: litex_gpio_read
+ *
+ * Description:
+ *   Read one or zero from the selected GPIO pin.
+ *
+ * Input Parameters:
+ *   port      - The GPIO port number to read from.
+ *   pin       - The pin, or bit offset inside the GPIO port.
+ *
+ * Returned Value:
+ *   True if the pin is logic high. False if the pin is logic low.
+ *
+ ****************************************************************************/
+
+bool litex_gpio_read(uint32_t port, uint32_t pin)
+{
+  return (getreg32(gpiobase_at(port) + GPIO_REG_IN_OFFSET) >> pin) & 0x1;
+}
+
+/****************************************************************************
+ * Name: litex_gpio_irq_enable
+ *
+ * Description:
+ *   Initialize logic to support a second level of interrupt decoding for
+ *   GPIO pins on the GPIO port.
+ *
+ * Input Parameters:
+ *   irq       - The IRQ number to enable. Must be a hardware interrupt
+ *               number as defined in irq.h.
+ *
+ * Returned Value:
+ *   Zero (OK) is returned on success; a negated errno value is returned
+ *   on failure.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_LITEX_GPIO_IRQ
+int litex_gpio_irq_enable(int irq)
+{
+  int ret;
+  up_disable_irq(irq);
+  ret = irq_attach(irq, litex_gpio_interrupt, NULL);
+  if (ret == OK)
+    {
+      up_enable_irq(irq);
+    }
+
+  return ret;
+}
+#endif
+
+/****************************************************************************
+ * Name: litex_gpio_irq_configure
+ *
+ * Description:
+ *   Enable the interrupt for specified GPIO IRQ.
+ *
+ * Input Parameters:
+ *   config      - The interrupt configuration.
+ *
+ * Returned Value:
+ *   Zero (OK) is returned on success; a negated errno value is returned
+ *   on failure.
+ ****************************************************************************/
+
+#ifdef CONFIG_LITEX_GPIO_IRQ
+int litex_gpio_irq_config(struct gpio_isr_config_t * config)
+{
+  int bitmask = 0x1 << config->pin;
+  int irq = gpio_index_to_irq(config->port, config->pin);
+  int ret = OK;
+  uint32_t gpiobase = gpiobase_at(config->port);
+
+  if (config->type & GPIO_ISR_NONE)
+    {
+      modifyreg32(gpiobase + GPIO_REG_EV_PEND_OFFSET, bitmask, bitmask);
+      modifyreg32(gpiobase + GPIO_REG_EV_ENABLE_OFFSET, bitmask, 0);
+      return OK;
+    }
+
+  if (config->handler)
+    {
+      ret = irq_attach(irq, config->handler, config->userdata);
+    }
+
+  if (ret != OK)
+    {
+      return -ENODEV;

Review Comment:
   ```suggestion
         return ret;
   ```



##########
arch/risc-v/src/litex/litex_gpio.h:
##########
@@ -0,0 +1,210 @@
+/****************************************************************************
+ * arch/risc-v/src/litex/litex_gpio.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_RISCV_SRC_LITEX_LITEX_GPIO_H
+#define __ARCH_RISCV_SRC_LITEX_LITEX_GPIO_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/irq.h>
+
+#include <stdint.h>
+#include <stdbool.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Encoded pin attributes used with gpio_pinattr_t */
+#define GPIO_PINMODE_INPUT      1   /* Pin is set to input mode. */
+#define GPIO_PINMODE_OUTPUT     2   /* Pin is set to output mode. */
+
+/* Encoded pin attributes used with gpio_intertype_t */
+#define GPIO_ISR_NONE           1  /* Disables interrupts */
+#define GPIO_ISR_RISING_EDGE    2  /* Interrupt generated on rising edge. */
+#define GPIO_ISR_FALLING_EDGE   4  /* Interrupt generated on falling edge. */
+#define GPIO_ISR_BOTH_EDGES     8  /* Interrupt generated on both edges. */
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+#ifndef __ASSEMBLY__
+
+/* Describes attributes used to configure GPIO pins */
+
+typedef uint32_t gpio_pinattr_t;
+
+/* Describes attributes used to enable / disable GPIO interrupts. */
+
+typedef uint32_t gpio_intrtype_t;
+
+struct gpio_isr_config_t

Review Comment:
   ```suggestion
   struct gpio_isr_config_s
   ```



##########
arch/risc-v/src/litex/litex_gpio.c:
##########
@@ -0,0 +1,357 @@
+/****************************************************************************
+ * arch/risc-v/src/litex/litex_gpio.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <assert.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <arch/irq.h>
+
+#include "riscv_internal.h"
+#include "litex_gpio.h"
+#include "litex_memorymap.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define GPIO_REG_OE_OFFSET          0x00
+#define GPIO_REG_IN_OFFSET          0x04
+#define GPIO_REG_OUT_OFFSET         0x08
+#define GPIO_REG_MODE_OFFSET        0x0C
+#define GPIO_REG_EDGE_OFFSET        0x10
+#define GPIO_REG_EV_STATUS_OFFSET   0x14
+#define GPIO_REG_EV_PEND_OFFSET     0x18
+#define GPIO_REG_EV_ENABLE_OFFSET   0x1C
+
+#ifdef CONFIG_LITEX_GPIO_IRQ
+/* Helper to calculate the GPIO port index from an IRQ number. */
+#define irq_to_gpio_index(_irqno) (( _irqno - LITEX_IRQ_GPIO) % 32)
+
+/* Helper to calculate the extended IRQ number from GPIO  port index. */
+#define gpio_index_to_irq(_i, _p) ((_i * 32) + _p + LITEX_FIRST_GPIOIRQ)
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions Prototypes
+ ****************************************************************************/
+
+static uint32_t gpiobase_at(uint32_t index);
+
+#ifdef CONFIG_LITEX_GPIO_IRQ
+static void gpio_dispatch(int irq, uint32_t gpiobase, uint32_t * regs);
+static int litex_gpio_interrupt(int irq, void *context, void * arg);
+#endif
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* A lookup table to keep track of all the base addresses for all gateware
+ * defined GPIO peripherals. This saves calculating the actual base address
+ * in the ISR routines, as there is only an IRQ number available at that
+ * point.
+ *
+ * The actual memory addresses are populated the first time it is used.
+ */
+
+static uint32_t gpio_base_s[LITEX_GPIO_MAX] =

Review Comment:
   ```suggestion
   static uint32_t g_gpio_base[LITEX_GPIO_MAX] =
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] xiaoxiang781216 merged pull request #8368: litex: Add GPIO driver.

Posted by "xiaoxiang781216 (via GitHub)" <gi...@apache.org>.
xiaoxiang781216 merged PR #8368:
URL: https://github.com/apache/nuttx/pull/8368


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] g2gps commented on a diff in pull request #8368: litex: Add GPIO driver.

Posted by "g2gps (via GitHub)" <gi...@apache.org>.
g2gps commented on code in PR #8368:
URL: https://github.com/apache/nuttx/pull/8368#discussion_r1092534840


##########
arch/risc-v/src/litex/litex_gpio.c:
##########
@@ -0,0 +1,357 @@
+/****************************************************************************
+ * arch/risc-v/src/litex/litex_gpio.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <assert.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <arch/irq.h>
+
+#include "riscv_internal.h"
+#include "litex_gpio.h"
+#include "litex_memorymap.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define GPIO_REG_OE_OFFSET          0x00
+#define GPIO_REG_IN_OFFSET          0x04
+#define GPIO_REG_OUT_OFFSET         0x08
+#define GPIO_REG_MODE_OFFSET        0x0C
+#define GPIO_REG_EDGE_OFFSET        0x10
+#define GPIO_REG_EV_STATUS_OFFSET   0x14
+#define GPIO_REG_EV_PEND_OFFSET     0x18
+#define GPIO_REG_EV_ENABLE_OFFSET   0x1C
+
+#ifdef CONFIG_LITEX_GPIO_IRQ
+/* Helper to calculate the GPIO port index from an IRQ number. */
+#define irq_to_gpio_index(_irqno) (( _irqno - LITEX_IRQ_GPIO) % 32)
+
+/* Helper to calculate the extended IRQ number from GPIO  port index. */
+#define gpio_index_to_irq(_i, _p) ((_i * 32) + _p + LITEX_FIRST_GPIOIRQ)
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions Prototypes
+ ****************************************************************************/
+
+static uint32_t gpiobase_at(uint32_t index);
+
+#ifdef CONFIG_LITEX_GPIO_IRQ
+static void gpio_dispatch(int irq, uint32_t gpiobase, uint32_t * regs);
+static int litex_gpio_interrupt(int irq, void *context, void * arg);
+#endif
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* A lookup table to keep track of all the base addresses for all gateware
+ * defined GPIO peripherals. This saves calculating the actual base address
+ * in the ISR routines, as there is only an IRQ number available at that
+ * point.
+ *
+ * The actual memory addresses are populated the first time it is used.
+ */
+
+static uint32_t gpio_base_s[LITEX_GPIO_MAX] =
+{
+  0
+};
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static uint32_t gpiobase_at(uint32_t index)
+{
+  DEBUGASSERT(index < LITEX_GPIO_MAX);
+  if (gpio_base_s[0] == 0)
+    {
+      for (int i = 0; i < LITEX_GPIO_MAX; i++)
+        {
+          gpio_base_s[i] = LITEX_GPIO_BASE +
+                          (LITEX_GPIO_OFFSET * i);
+        }
+    }
+
+  return gpio_base_s[index];
+}
+
+#ifdef CONFIG_LITEX_GPIO_IRQ
+static void gpio_dispatch(int irq, uint32_t gpiobase, uint32_t * regs)
+{
+  int i;
+  int ndx = 0;
+  uint32_t bitmask;
+
+  /* Query which pin interrupts are enabled */
+
+  uint32_t enabled = getreg32(gpiobase + GPIO_REG_EV_ENABLE_OFFSET);
+
+  /* Query which interrupts are pending */
+
+  uint32_t pending = getreg32(gpiobase + GPIO_REG_EV_PEND_OFFSET);
+
+  while ((i = __builtin_ffs(pending)))

Review Comment:
   I modified this to use Nuttx's version, as I guess it is possible that a compiler is used which doesn't support this.  `CONFIG_HAVE_BUILTIN_FFS` can always be enabled in order to use the builtin version.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org