From 5322f909efcef07cf114229257b86b63f48932ef Mon Sep 17 00:00:00 2001 From: Alan Carvalho de Assis Date: Tue, 13 Sep 2022 14:39:21 -0300 Subject: [PATCH] stm32f4discovery: Add support to WIZnet W5500 --- .../arm/stm32/stm32f4discovery/src/Make.defs | 4 + .../stm32/stm32f4discovery/src/stm32_spi.c | 15 ++ .../stm32/stm32f4discovery/src/stm32_w5500.c | 192 ++++++++++++++++++ .../stm32f4discovery/src/stm32f4discovery.h | 11 + 4 files changed, 222 insertions(+) create mode 100644 boards/arm/stm32/stm32f4discovery/src/stm32_w5500.c diff --git a/boards/arm/stm32/stm32f4discovery/src/Make.defs b/boards/arm/stm32/stm32f4discovery/src/Make.defs index 0542e7e855..6e17e93d6e 100644 --- a/boards/arm/stm32/stm32f4discovery/src/Make.defs +++ b/boards/arm/stm32/stm32f4discovery/src/Make.defs @@ -52,6 +52,10 @@ ifeq ($(CONFIG_ENC28J60),y) CSRCS += stm32_enc28j60.c endif +ifeq ($(CONFIG_NET_W5500),y) +CSRCS += stm32_w5500.c +endif + ifeq ($(CONFIG_LPWAN_SX127X),y) CSRCS += stm32_sx127x.c endif diff --git a/boards/arm/stm32/stm32f4discovery/src/stm32_spi.c b/boards/arm/stm32/stm32f4discovery/src/stm32_spi.c index 6e58e48435..cdb8d75c61 100644 --- a/boards/arm/stm32/stm32f4discovery/src/stm32_spi.c +++ b/boards/arm/stm32/stm32f4discovery/src/stm32_spi.c @@ -61,6 +61,12 @@ void weak_function stm32_spidev_initialize(void) stm32_configgpio(GPIO_ENC28J60_INTR); #endif +#ifdef CONFIG_NET_W5500 + stm32_configgpio(GPIO_W5500_CS); + stm32_configgpio(GPIO_W5500_RESET); + stm32_configgpio(GPIO_W5500_INTR); +#endif + #ifdef CONFIG_STM32_SPI1 stm32_configgpio(GPIO_CS_MEMS); /* MEMS chip select */ #endif @@ -134,6 +140,15 @@ void stm32_spi1select(struct spi_dev_s *dev, uint32_t devid, } #endif +#ifdef CONFIG_NET_W5500 + if (devid == SPIDEV_ETHERNET(0)) + { + /* Set the GPIO low to select and high to de-select */ + + stm32_gpiowrite(GPIO_W5500_CS, !selected); + } +#endif + #ifdef CONFIG_LPWAN_SX127X if (devid == SPIDEV_LPWAN(0)) { diff --git a/boards/arm/stm32/stm32f4discovery/src/stm32_w5500.c b/boards/arm/stm32/stm32f4discovery/src/stm32_w5500.c new file mode 100644 index 0000000000..13105a9768 --- /dev/null +++ b/boards/arm/stm32/stm32f4discovery/src/stm32_w5500.c @@ -0,0 +1,192 @@ +/**************************************************************************** + * boards/arm/stm32/stm32f4discovery/src/stm32_w5500.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 + +#include +#include +#include +#include + +#include +#include + +#include + +#include "chip.h" +#include "arm_internal.h" +#include "stm32_spi.h" + +#include "stm32f4discovery.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ + +/* W5500 is on SPI1 */ + +#ifndef CONFIG_STM32_SPI1 +# error "Need CONFIG_STM32_SPI1 in the configuration" +#endif + +/* SPI Assumptions **********************************************************/ + +#define W5500_SPI_PORTNO 1 /* On SPI1 */ +#define W5500_DEVNO 0 /* Only one W5500 */ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct stm32_lower_s +{ + const struct w5500_lower_s lower; /* Low-level MCU interface */ + xcpt_t handler; /* W5500 interrupt handler */ + void *arg; /* Argument that accompanies IRQ */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int up_attach(const struct w5500_lower_s *lower, xcpt_t handler, + void *arg); +static void up_enable(const struct w5500_lower_s *lower, bool enable); +static void up_reset(const struct w5500_lower_s *lower, bool reset); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* The W5500 normal provides interrupts to the MCU via a GPIO pin. The + * following structure provides an MCU-independent mechanism for controlling + * the W5500 GPIO interrupt. + */ + +static struct stm32_lower_s g_enclower = +{ + .lower = + { + .frequency = 10000000, + .spidevid = 0, + .mode = SPIDEV_MODE0, + .attach = up_attach, + .enable = up_enable, + .reset = up_reset, + }, + .handler = NULL, + .arg = NULL +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: struct w5500_lower_s methods + ****************************************************************************/ + +static int up_attach(const struct w5500_lower_s *lower, xcpt_t handler, + void *arg) +{ + struct stm32_lower_s *priv = (struct stm32_lower_s *)lower; + + /* Just save the handler for use when the interrupt is enabled */ + + priv->handler = handler; + priv->arg = arg; + return OK; +} + +static void up_enable(const struct w5500_lower_s *lower, bool enable) +{ + struct stm32_lower_s *priv = (struct stm32_lower_s *)lower; + + DEBUGASSERT(priv->handler); + if (enable) + { + stm32_gpiosetevent(GPIO_W5500_INTR, false, true, true, + priv->handler, priv->arg); + } + else + { + stm32_gpiosetevent(GPIO_W5500_INTR, false, true, true, + NULL, NULL); + } +} + +/* REVISIT: Since the interrupt is completely torn down, not just disabled, + * in interrupt requests that occurs while the interrupt is disabled will be + * lost. + */ + +static void up_reset(const struct w5500_lower_s *lower, bool reset) +{ + /* Take W5500 out of reset (active low) */ + + stm32_gpiowrite(GPIO_W5500_RESET, !reset); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: arm_netinitialize + ****************************************************************************/ + +void arm_netinitialize(void) +{ + struct spi_dev_s *spi; + int ret; + + /* Assumptions: + * 1) W5500 pins were configured in up_spi.c early in the boot-up phase. + * 2) Clocking for the SPI1 peripheral was also provided earlier in + * boot-up. + */ + + spi = stm32_spibus_initialize(W5500_SPI_PORTNO); + if (!spi) + { + nerr("ERROR: Failed to initialize SPI port %d\n", W5500_SPI_PORTNO); + return; + } + + /* Bind the SPI port to the W5500 driver */ + + ret = w5500_initialize(spi, &g_enclower.lower, W5500_DEVNO); + if (ret < 0) + { + nerr("ERROR: Failed to bind SPI port %d W5500 device %d: %d\n", + W5500_SPI_PORTNO, W5500_DEVNO, ret); + return; + } + + ninfo("Bound SPI port %d to W5500 device %d\n", + W5500_SPI_PORTNO, W5500_DEVNO); +} + diff --git a/boards/arm/stm32/stm32f4discovery/src/stm32f4discovery.h b/boards/arm/stm32/stm32f4discovery/src/stm32f4discovery.h index d35c0b2f91..ff056b4868 100644 --- a/boards/arm/stm32/stm32f4discovery/src/stm32f4discovery.h +++ b/boards/arm/stm32/stm32f4discovery/src/stm32f4discovery.h @@ -289,6 +289,17 @@ #define GPIO_ENC28J60_INTR (GPIO_INPUT|GPIO_FLOAT|GPIO_EXTI|\ GPIO_OPENDRAIN|GPIO_PORTE|GPIO_PIN4) +/* Use same pins as ENC28J60 to W5500 */ + +#define GPIO_W5500_CS (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_50MHz|\ + GPIO_OUTPUT_SET|GPIO_PORTA|GPIO_PIN4) + +#define GPIO_W5500_RESET (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_50MHz|\ + GPIO_OUTPUT_CLEAR|GPIO_PORTE|GPIO_PIN1) + +#define GPIO_W5500_INTR (GPIO_INPUT|GPIO_FLOAT|GPIO_EXTI|\ + GPIO_OPENDRAIN|GPIO_PORTE|GPIO_PIN4) + /* USB OTG FS * * PA9 OTG_FS_VBUS VBUS sensing (also connected to the green LED)