This is an automated email from the ASF dual-hosted git repository.

acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 3ce84d1ba0e7bfd2c21ad79edb762d10ca4d289c
Author: Jakub Janousek <janou...@fel.cvut.cz>
AuthorDate: Thu Mar 21 16:29:22 2024 +0100

    arch and board esp32c3-legacy: Add optional iCE40 FPGA loading support
    
    Signed-off-by: Jakub Janousek <janou...@fel.cvut.cz>
---
 arch/risc-v/src/esp32c3-legacy/Kconfig             |  25 +++
 arch/risc-v/src/esp32c3-legacy/Make.defs           |   4 +
 arch/risc-v/src/esp32c3-legacy/esp32c3_ice40.c     | 214 +++++++++++++++++++++
 arch/risc-v/src/esp32c3-legacy/esp32c3_ice40.h     |  91 +++++++++
 .../common/include/esp32c3_board_ice40.h           |  70 +++++++
 boards/risc-v/esp32c3-legacy/common/src/Make.defs  |   4 +
 .../common/src/esp32c3_board_ice40.c               |  82 ++++++++
 .../esp32c3-devkit/src/esp32c3_bringup.c           |   9 +
 8 files changed, 499 insertions(+)

diff --git a/arch/risc-v/src/esp32c3-legacy/Kconfig 
b/arch/risc-v/src/esp32c3-legacy/Kconfig
index 2e9bdae0b7..99d3140341 100644
--- a/arch/risc-v/src/esp32c3-legacy/Kconfig
+++ b/arch/risc-v/src/esp32c3-legacy/Kconfig
@@ -516,6 +516,31 @@ endif # ESP32C3_SPI2
 
 endmenu # SPI configuration
 
+menu "iCE40 Configuration"
+       depends on SPI_ICE40
+
+config ESP32C3_ICE40_CSPIN
+       int "iCE40 CS Pin"
+       default 6
+       range 0 21
+
+config ESP32C3_ICE40_CDONEPIN
+       int "iCE40 CDONE Pin"
+       default 0
+       range 0 21
+
+config ESP32C3_ICE40_CRSTPIN
+       int "iCE40 CRST Pin"
+       default 1
+       range 0 21
+
+config ESP32C3_ICE40_SPI_PORT
+       int "iCE40 SPI port number"
+       default 2
+       range 0 5
+
+endmenu
+
 menu "UART configuration"
        depends on ESP32C3_UART
 
diff --git a/arch/risc-v/src/esp32c3-legacy/Make.defs 
b/arch/risc-v/src/esp32c3-legacy/Make.defs
index 23ad159619..73ed5f3330 100644
--- a/arch/risc-v/src/esp32c3-legacy/Make.defs
+++ b/arch/risc-v/src/esp32c3-legacy/Make.defs
@@ -181,6 +181,10 @@ ifeq ($(CONFIG_ESP32C3_BROWNOUT_DET),y)
 CHIP_CSRCS += esp32c3_brownout.c
 endif
 
+ifeq ($(CONFIG_SPI_ICE40),y)
+CHIP_CSRCS += esp32c3_ice40.c
+endif
+
 ifeq ($(CONFIG_ESP32C3_WIRELESS),y)
 WIRELESS_DRV_UNPACK = esp-wireless-drivers-3rdparty
 WIRELESS_DRV_ID     = 45701c0
diff --git a/arch/risc-v/src/esp32c3-legacy/esp32c3_ice40.c 
b/arch/risc-v/src/esp32c3-legacy/esp32c3_ice40.c
new file mode 100644
index 0000000000..823c4e15d8
--- /dev/null
+++ b/arch/risc-v/src/esp32c3-legacy/esp32c3_ice40.c
@@ -0,0 +1,214 @@
+/****************************************************************************
+ * arch/risc-v/src/esp32c3-legacy/esp32c3_ice40.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 <nuttx/nuttx.h>
+
+#include <assert.h>
+#include <debug.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+
+#include <arch/board/board.h>
+#include <arch/esp32c3-legacy/chip.h>
+#include <arch/irq.h>
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/kmalloc.h>
+#include <nuttx/spi/ice40.h>
+#include <nuttx/spi/spi.h>
+
+#include "esp32c3_spi.h"
+#include "hardware/esp32c3_spi.h"
+
+#include "hardware/esp32c3_gpio.h"
+#include "hardware/esp32c3_gpio_sigmap.h"
+
+#include "esp32c3_ice40.h"
+
+#include "esp32c3_gpio.h"
+
+#include <nuttx/spi/ice40.h>
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static void ice40_reset(struct ice40_dev_s *dev, bool reset);
+static void ice40_select(struct ice40_dev_s *dev, bool select);
+static bool ice40_get_status(struct ice40_dev_s *dev);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const struct ice40_ops_s ice40_ops =
+{
+  .reset = ice40_reset,
+  .select = ice40_select,
+  .get_status = ice40_get_status,
+};
+
+struct esp32c3_ice40_dev_s
+{
+  struct ice40_dev_s base;
+  uint16_t cdone_gpio;
+  uint16_t crst_gpio;
+  uint16_t cs_gpio;
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: ice40_reset
+ *
+ * Description:
+ *  Reset ICE40 FPGA
+ *
+ * Input Parameters:
+ *  reset - true to reset, false to release reset (inverse logic, active low)
+ *
+ ****************************************************************************/
+
+static void
+ice40_reset(struct ice40_dev_s *dev, bool reset)
+{
+  struct esp32c3_ice40_dev_s *priv
+      = container_of (dev, struct esp32c3_ice40_dev_s, base);
+  esp32c3_gpiowrite(priv->crst_gpio, !reset);
+}
+
+/****************************************************************************
+ * Name: ice40_select
+ *
+ * Description:
+ *  Select ICE40 FPGA
+ *
+ * Input Parameters:
+ *  select - true to select, false to deselect (inverse logic, active low)
+ *
+ ****************************************************************************/
+
+static void
+ice40_select(struct ice40_dev_s *dev, bool select)
+{
+  struct esp32c3_ice40_dev_s *priv
+      = container_of (dev, struct esp32c3_ice40_dev_s, base);
+  esp32c3_gpiowrite(priv->cs_gpio, !select);
+}
+
+/****************************************************************************
+ * Name: ice40_get_status
+ *
+ * Description:
+ *  Get ICE40 FPGA status via CDONE pin. Important to know if the FPGA is
+ *  programmed and ready to use.
+ *
+ * Returned Value:
+ *  true if the FPGA is programmed and ready to use, false otherwise.
+ *
+ ****************************************************************************/
+
+static bool
+ice40_get_status(struct ice40_dev_s *dev)
+{
+  struct esp32c3_ice40_dev_s *priv
+      = container_of(dev, struct esp32c3_ice40_dev_s, base);
+  return esp32c3_gpioread (priv->cdone_gpio);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32c3_ice40_initialize
+ *
+ * Description:
+ *  Initialize ICE40 FPGA GPIOs and SPI.
+ *
+ * Input Parameters:
+ *
+ *
+ ****************************************************************************/
+
+FAR struct ice40_dev_s *
+esp32c3_ice40_initialize(const uint16_t cdone_gpio,
+                          const uint16_t crst_gpio,
+                          const uint16_t cs_gpio,
+                          const uint16_t spi_port)
+{
+  struct esp32c3_ice40_dev_s *ice40_ptr;
+
+  ice40_ptr = kmm_malloc(sizeof(struct esp32c3_ice40_dev_s));
+  if (ice40_ptr == NULL)
+    {
+      spierr("ERROR: Failed to allocate memory for ICE40 driver\n");
+      return NULL;
+    }
+
+  memset(ice40_ptr, 0, sizeof (struct esp32c3_ice40_dev_s));
+
+  ice40_ptr->base.ops = &ice40_ops;
+
+  /* Configure GPIO pins */
+
+  DEBUGASSERT(0 <= cdone_gpio && cdone_gpio < 32);
+  DEBUGASSERT(0 <= crst_gpio && crst_gpio < 32);
+  DEBUGASSERT(0 <= cs_gpio && cs_gpio < 32);
+  DEBUGASSERT(0 <= spi_port && spi_port < 3);
+
+  esp32c3_gpio_matrix_out(cdone_gpio, SIG_GPIO_OUT_IDX, 0, 0);
+  esp32c3_gpio_matrix_out(crst_gpio, SIG_GPIO_OUT_IDX, 0, 0);
+  esp32c3_gpio_matrix_out(cs_gpio, SIG_GPIO_OUT_IDX, 0, 0);
+
+  esp32c3_configgpio(cdone_gpio, INPUT_FUNCTION_1 | PULLDOWN);
+  esp32c3_configgpio(crst_gpio, OUTPUT_FUNCTION_1);
+  esp32c3_configgpio(cs_gpio, OUTPUT_FUNCTION_1);
+
+  esp32c3_gpiowrite(crst_gpio, 1);
+  esp32c3_gpiowrite(cs_gpio, 1);
+
+  ice40_ptr->cdone_gpio = cdone_gpio;
+  ice40_ptr->crst_gpio = crst_gpio;
+  ice40_ptr->cs_gpio = cs_gpio;
+
+  /* Configure SPI */
+
+  ice40_ptr->base.spi = esp32c3_spibus_initialize(spi_port);
+  if (ice40_ptr->base.spi == NULL)
+    {
+      spierr("ERROR: Failed to initialize SPI port %d\n",
+              ice40_ptr->base.spi);
+      return NULL;
+    }
+
+  return &ice40_ptr->base;
+}
diff --git a/arch/risc-v/src/esp32c3-legacy/esp32c3_ice40.h 
b/arch/risc-v/src/esp32c3-legacy/esp32c3_ice40.h
new file mode 100644
index 0000000000..1669fe7076
--- /dev/null
+++ b/arch/risc-v/src/esp32c3-legacy/esp32c3_ice40.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+ * arch/risc-v/src/esp32c3-legacy/esp32c3_ice40.h
+ *
+ * Licensed 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_ESP32C3_LEGACY_HARDWARE_ESP32C3_ICE40_H
+#define __ARCH_RISCV_SRC_ESP32C3_LEGACY_HARDWARE_ESP32C3_ICE40_H
+
+/****************************************************************************
+ * Included Files
+ * *************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <assert.h>
+#include <debug.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+
+#include <arch/board/board.h>
+#include <arch/esp32c3-legacy/chip.h>
+#include <nuttx/arch.h>
+
+#include <nuttx/spi/ice40.h>
+#include <nuttx/spi/spi.h>
+
+#include "hardware/esp32c3_gpio.h"
+#include "hardware/esp32c3_gpio_sigmap.h"
+
+#include "esp32c3_gpio.h"
+
+#ifndef __ASSEMBLY__
+#undef EXTERN
+#if defined(__cplusplus)
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32c3_ice40_initialize
+ *
+ * Description:
+ *  Initialize ICE40 FPGA GPIOs and SPI interface.
+ *
+ * Input Parameters:
+ *  cdone_gpio - GPIO pin connected to the CDONE pin of the ICE40 FPGA.
+ *  crst_gpio - GPIO pin connected to the CRST pin of the ICE40 FPGA.
+ *  cs_gpio - GPIO pin connected to the CS pin of the ICE40 FPGA.
+ *  spi_port - SPI port number to use for communication with the ICE40 FPGA.
+ *
+ * Returned Value:
+ *  A reference to the initialized ICE40 FPGA driver instance.
+ *  NULL in case of failure.
+ *
+ ****************************************************************************/
+
+  struct ice40_dev_s *esp32c3_ice40_initialize(const uint16_t cdone_gpio,
+                                               const uint16_t crst_gpio,
+                                               const uint16_t cs_gpio,
+                                               const uint16_t spi_port);
+
+#undef EXTERN
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ARCH_RISCV_SRC_ESP32C3_LEGACY_HARDWARE_ESP32C3_ICE40_H */
diff --git a/boards/risc-v/esp32c3-legacy/common/include/esp32c3_board_ice40.h 
b/boards/risc-v/esp32c3-legacy/common/include/esp32c3_board_ice40.h
new file mode 100644
index 0000000000..935077d7ee
--- /dev/null
+++ b/boards/risc-v/esp32c3-legacy/common/include/esp32c3_board_ice40.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+ * boards/risc-v/esp32c3-legacy/common/include/esp32c3_board_ice40.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 __BOARDS_RISCV_ESP32C3_LEGACY_COMMON_INCLUDE_ESP32C3_BOARD_ICE40_H
+#define __BOARDS_RISCV_ESP32C3_LEGACY_COMMON_INCLUDE_ESP32C3_BOARD_ICE40_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifndef __ASSEMBLY__
+
+#undef EXTERN
+#if defined(__cplusplus)
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32c3_ice40_setup
+ *
+ * Description:
+ *  Initialize ICE40 FPGA GPIOs, SPI and register the ICE40 driver.
+ *
+ * Returned Value:
+ *  Zero (OK) on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_SPI_ICE40
+int esp32c3_ice40_setup(void);
+#endif
+
+#undef EXTERN
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* __ASSEMBLY__ */
+#endif /* __BOARDS_RISCV_ESP32C3_COMMON_INCLUDE_ESP32C3_BOARD_BMP180_H */
diff --git a/boards/risc-v/esp32c3-legacy/common/src/Make.defs 
b/boards/risc-v/esp32c3-legacy/common/src/Make.defs
index 25cdfc2e1c..1c1720e25a 100644
--- a/boards/risc-v/esp32c3-legacy/common/src/Make.defs
+++ b/boards/risc-v/esp32c3-legacy/common/src/Make.defs
@@ -92,6 +92,10 @@ ifeq ($(CONFIG_MPU60X0_I2C),y)
   CSRCS += esp32c3_board_mpu60x0_i2c.c
 endif
 
+ifeq ($(CONFIG_SPI_ICE40),y)
+  CSRCS += esp32c3_board_ice40.c
+endif
+
 DEPPATH += --dep-path src
 VPATH += :src
 CFLAGS += 
${INCDIR_PREFIX}$(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)board$(DELIM)src
diff --git a/boards/risc-v/esp32c3-legacy/common/src/esp32c3_board_ice40.c 
b/boards/risc-v/esp32c3-legacy/common/src/esp32c3_board_ice40.c
new file mode 100644
index 0000000000..f5e1ef1a01
--- /dev/null
+++ b/boards/risc-v/esp32c3-legacy/common/src/esp32c3_board_ice40.c
@@ -0,0 +1,82 @@
+/****************************************************************************
+ * boards/risc-v/esp32c3-legacy/common/src/esp32c3_board_ice40.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 <assert.h>
+#include <debug.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <arch/board/board.h>
+#include <arch/esp32c3-legacy/chip.h>
+#include <nuttx/arch.h>
+#include <nuttx/board.h>
+
+#include "nuttx/spi/ice40.h"
+
+#include "esp32c3_ice40.h"
+#include "esp32c3_board_ice40.h"
+
+#include "esp32c3_gpio.h"
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32c3_ice40_setup
+ *
+ * Description:
+ *  Initialize ICE40 FPGA GPIOs, SPI and register the ICE40 driver.
+ *
+ ****************************************************************************/
+
+int esp32c3_ice40_setup(void)
+{
+  struct ice40_dev_s *ice40;
+
+  /* Initialize ICE40 FPGA GPIOs and SPI interface */
+
+  ice40 = esp32c3_ice40_initialize(CONFIG_ESP32C3_ICE40_CDONEPIN,
+                                   CONFIG_ESP32C3_ICE40_CRSTPIN,
+                                   CONFIG_ESP32C3_ICE40_CSPIN,
+                                   CONFIG_ESP32C3_ICE40_SPI_PORT);
+  if (ice40 <= 0)
+    {
+      _err("ERROR: Failed to initialize ICE40 driver\n");
+      return -ENODEV;
+    }
+
+  /* Register the ICE40 FPGA device at "/dev/ice40-0" */
+
+  int ret = ice40_register("/dev/ice40-0", ice40);
+  if (ret < 0)
+    {
+      _err("ERROR: Failed to register ICE40 driver: %d\n", ret);
+      return ret;
+    }
+
+  return OK;
+}
diff --git a/boards/risc-v/esp32c3-legacy/esp32c3-devkit/src/esp32c3_bringup.c 
b/boards/risc-v/esp32c3-legacy/esp32c3-devkit/src/esp32c3_bringup.c
index 7fb9e542b9..9e8acf4582 100644
--- a/boards/risc-v/esp32c3-legacy/esp32c3-devkit/src/esp32c3_bringup.c
+++ b/boards/risc-v/esp32c3-legacy/esp32c3-devkit/src/esp32c3_bringup.c
@@ -54,6 +54,7 @@
 #include "esp32c3_board_wdt.h"
 #include "esp32c3_board_wlan.h"
 #include "esp32c3_board_mpu60x0_i2c.h"
+#include "esp32c3_board_ice40.h"
 
 #ifdef CONFIG_SPI
 #  include "esp32c3_spi.h"
@@ -386,6 +387,14 @@ int esp32c3_bringup(void)
     }
 #endif
 
+#ifdef CONFIG_SPI_ICE40
+  ret = esp32c3_ice40_setup();
+  if (ret < 0)
+    {
+      syslog(LOG_ERR, "ERROR: Failed to initialize ICE40: %d\n", ret);
+    }
+#endif
+
   /* If we got here then perhaps not all initialization was successful, but
    * at least enough succeeded to bring-up NSH with perhaps reduced
    * capabilities.

Reply via email to