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.