Skip to content

Commit

Permalink
drivers: wifi: infineon: Add SPI support to AIROC WiFi driver
Browse files Browse the repository at this point in the history
Added support for SPI to the Infineon AIROC WiFi driver
(drivers/wifi/infineon).  Includes support for 3-wire SPI
required by the Raspberry Pi Pico W.

Configuration for the Pico W is updated to activate the
WiFi chip on that board.

Added cleanup following review comments.

Signed-off-by: Steve Boylan <stephen.boylan@beechwoods.com>
  • Loading branch information
ThreeEights committed Sep 23, 2024
1 parent 23eca63 commit f41933d
Show file tree
Hide file tree
Showing 15 changed files with 671 additions and 118 deletions.
18 changes: 18 additions & 0 deletions boards/raspberrypi/rpi_pico/doc/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,24 @@ devices as well as both PIO devices).
Programming and Debugging
*************************

System requirements
===================

Prerequisites for the Pico W
----------------------------

Building for the RaspberryPi Pico W requires the AIROC binary blobs
provided by `Infineon <boards-infineon_>`_. Run the command
below to retrieve those files.

.. code-block:: console
west blobs fetch hal_infineon
.. note::

It is recommended running the command above after :file:`west update`.

Flashing
========

Expand Down
38 changes: 38 additions & 0 deletions boards/raspberrypi/rpi_pico/rpi_pico_rp2040_w.dts
Original file line number Diff line number Diff line change
@@ -1,9 +1,47 @@
/*
* Copyright (c) 2023 Dave Rensberger - Beechwoods Software
* Copyright (c) 2024 Steve Boylan <stephen.boylan@beechwoods.com>
*
* SPDX-License-Identifier: Apache-2.0
*/

/dts-v1/;

#include "rpi_pico-common.dtsi"

&pinctrl {
pio0_spi0_default: pio0_spi0_default {
/* gpio 25 is used for chip select, not assigned to the PIO */
group1 {
pinmux = <PIO0_P24>, <PIO0_P29>;
};
};
};

&pio0 {
status = "okay";

pio0_spi0: pio0_spi0 {
pinctrl-0 = <&pio0_spi0_default>;
pinctrl-names = "default";

compatible = "raspberrypi,pico-spi-pio";
status = "okay";
#address-cells = <1>;
#size-cells = <0>;
clocks = < &clocks RPI_PICO_CLKID_CLK_SYS >;
cs-gpios = <&gpio0 25 GPIO_ACTIVE_LOW>;
clk-gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>;
sio-gpios = <&gpio0 24 GPIO_ACTIVE_HIGH>;
airoc-wifi@0 {
status = "okay";
reg = < 0 >;
compatible = "infineon,airoc-wifi";
wifi-reg-on-gpios = < &gpio0 23 GPIO_ACTIVE_HIGH >;
bus-select-gpios = < &gpio0 24 GPIO_ACTIVE_HIGH >;
wifi-host-wake-gpios = < &gpio0 24 GPIO_ACTIVE_HIGH >;
spi-max-frequency = < 10000000 >;
spi-half-duplex;
};
};
};
20 changes: 20 additions & 0 deletions boards/raspberrypi/rpi_pico/rpi_pico_rp2040_w_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,23 @@ CONFIG_BUILD_OUTPUT_HEX=y
CONFIG_UART_INTERRUPT_DRIVEN=y
CONFIG_RESET=y
CONFIG_CLOCK_CONTROL=y

# Increase memory areas for WiFi stack
CONFIG_MAIN_STACK_SIZE=4096
CONFIG_HEAP_MEM_POOL_SIZE=16384
CONFIG_SHELL_STACK_SIZE=2560

# Default networking configuration
CONFIG_WIFI=y
CONFIG_NETWORKING=y
CONFIG_NET_L2_ETHERNET=y
CONFIG_NET_IPV6=n
CONFIG_NET_IPV4=y
CONFIG_NET_DHCPV4=y
CONFIG_NET_LOG=y
CONFIG_WIFI_AIROC=y
CONFIG_AIROC_WIFI_COUNTRY="US"
CONFIG_AIROC_WIFI_BUS_SDIO=n
CONFIG_AIROC_WIFI_BUS_SPI=y
CONFIG_AIROC_WIFI_BUS_SPI_DATA_IRQ_MUX=y
CONFIG_CYW43439=y
4 changes: 3 additions & 1 deletion drivers/wifi/infineon/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
zephyr_include_directories(./)

zephyr_library_sources_ifdef(CONFIG_WIFI_AIROC airoc_wifi.c)
zephyr_library_sources_ifdef(CONFIG_WIFI_AIROC airoc_whd_hal.c)
zephyr_library_sources_ifdef(CONFIG_WIFI_AIROC airoc_whd_hal_common.c)
zephyr_library_sources_ifdef(CONFIG_AIROC_WIFI_BUS_SDIO airoc_whd_hal_sdio.c)
zephyr_library_sources_ifdef(CONFIG_AIROC_WIFI_BUS_SPI airoc_whd_hal_spi.c)

zephyr_compile_definitions(CYBSP_WIFI_CAPABLE)
zephyr_compile_definitions(CY_RTOS_AWARE)
Expand Down
32 changes: 30 additions & 2 deletions drivers/wifi/infineon/Kconfig.airoc
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@ menuconfig WIFI_AIROC
bool "Infineon AIROC SoC Wi-Fi support"
select THREAD_CUSTOM_DATA
select WIFI_OFFLOAD
select NET_L2_ETHERNET
select NET_L2_WIFI_MGMT
select SDIO_STACK
select SDHC
select WIFI_USE_NATIVE_NETWORKING
select USE_INFINEON_ABSTRACTION_RTOS
depends on DT_HAS_INFINEON_AIROC_WIFI_ENABLED
Expand All @@ -17,6 +16,24 @@ menuconfig WIFI_AIROC

if WIFI_AIROC

choice
prompt "Bus Support"
default AIROC_WIFI_BUS_SDIO

config AIROC_WIFI_BUS_SDIO
bool "SDIO Interface"
select SDIO_STACK
select SDHC

config AIROC_WIFI_BUS_SPI
bool "SPI Interface"
select SPI

endchoice

config AIROC_WIFI_COUNTRY
string "Country code, see whd_country_code_t in whd_types.h"

config AIROC_WIFI_EVENT_TASK_STACK_SIZE
int "Event Task Stack Size"
default 4096
Expand All @@ -37,6 +54,17 @@ config AIROC_WIFI_CUSTOM
user must to provide path to FW, CLM and NVRAM for
custom or vendor CYW43xx modules.

if AIROC_WIFI_BUS_SPI

config AIROC_WIFI_BUS_SPI_DATA_IRQ_MUX
bool "Data and IRQ GPIO is shared"
help
Enable logic when the SPI data GPIO is shared
with the host wake interrupt, which requires
switching GPIO modes for that pin.

endif # AIROC_WIFI_BUS_SPI

choice AIROC_PART
prompt "Select AIROC part"
depends on !AIROC_WIFI_CUSTOM
Expand Down
86 changes: 86 additions & 0 deletions drivers/wifi/infineon/airoc_whd_hal_common.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
* Copyright (c) 2023 Cypress Semiconductor Corporation (an Infineon company) or
* an affiliate of Cypress Semiconductor Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/

#include "airoc_whd_hal_common.h"
#include "airoc_wifi.h"

#include <zephyr/kernel.h>
#include <zephyr/drivers/gpio.h>

#define DT_DRV_COMPAT infineon_airoc_wifi

LOG_MODULE_DECLARE(infineon_airoc_wifi, CONFIG_WIFI_LOG_LEVEL);

#ifdef __cplusplus
extern "C" {
#endif

/******************************************************
* Function
******************************************************/

int airoc_wifi_power_on(const struct device *dev)
{
#if DT_INST_NODE_HAS_PROP(0, wifi_reg_on_gpios)
int ret;
const struct airoc_wifi_config *config = dev->config;

/* Check WIFI REG_ON gpio instance */
if (!device_is_ready(config->wifi_reg_on_gpio.port)) {
LOG_ERR("Error: failed to configure wifi_reg_on %s pin %d",
config->wifi_reg_on_gpio.port->name, config->wifi_reg_on_gpio.pin);
return -EIO;
}

/* Configure wifi_reg_on as output */
ret = gpio_pin_configure_dt(&config->wifi_reg_on_gpio, GPIO_OUTPUT);
if (ret) {
LOG_ERR("Error %d: failed to configure wifi_reg_on %s pin %d", ret,
config->wifi_reg_on_gpio.port->name, config->wifi_reg_on_gpio.pin);
return ret;
}
ret = gpio_pin_set_dt(&config->wifi_reg_on_gpio, 0);
if (ret) {
return ret;
}

/* Allow CBUCK regulator to discharge */
k_msleep(WLAN_CBUCK_DISCHARGE_MS);

/* WIFI power on */
ret = gpio_pin_set_dt(&config->wifi_reg_on_gpio, 1);
if (ret) {
return ret;
}
k_msleep(WLAN_POWER_UP_DELAY_MS);
#endif /* DT_INST_NODE_HAS_PROP(0, reg_on_gpios) */

return 0;
}

/*
* Implement WHD memory wrappers
*/

void *whd_mem_malloc(size_t size)
{
return k_malloc(size);
}

void *whd_mem_calloc(size_t nitems, size_t size)
{
return k_calloc(nitems, size);
}

void whd_mem_free(void *ptr)
{
k_free(ptr);
}

#ifdef __cplusplus
} /* extern "C" */
#endif
60 changes: 60 additions & 0 deletions drivers/wifi/infineon/airoc_whd_hal_common.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* Copyright (c) 2023 Cypress Semiconductor Corporation (an Infineon company) or
* an affiliate of Cypress Semiconductor Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <whd.h>
#include <zephyr/device.h>

/** Defines the amount of stack memory available for the wifi thread. */
#if !defined(CY_WIFI_THREAD_STACK_SIZE)
#define CY_WIFI_THREAD_STACK_SIZE (5120)
#endif

/** Defines the priority of the thread that services wifi packets. Legal values are defined by the
* RTOS being used.
*/
#if !defined(CY_WIFI_THREAD_PRIORITY)
#define CY_WIFI_THREAD_PRIORITY (CY_RTOS_PRIORITY_HIGH)
#endif

/** Map Zephyr country codes (2 octets) to whd_country_code_t. */
#if defined(CONFIG_AIROC_WIFI_COUNTRY)
#if defined(CONFIG_BIG_ENDIAN)
#define AIROC_MAP_COUNTRY_CODE(code) ((code[1]) + (code[0] << 8))
#else
#define AIROC_MAP_COUNTRY_CODE(code) ((code[0]) + (code[1] << 8))
#endif
#endif

/** Defines the country this will operate in for wifi initialization parameters. See the
* wifi-host-driver's whd_country_code_t for legal options.
*/
#if !defined(CY_WIFI_COUNTRY)
#define CY_WIFI_COUNTRY (WHD_COUNTRY_AUSTRALIA)
#endif

/** Defines the priority of the interrupt that handles out-of-band notifications from the wifi
* chip. Legal values are defined by the MCU running this code.
*/
#if !defined(CY_WIFI_OOB_INTR_PRIORITY)
#define CY_WIFI_OOB_INTR_PRIORITY (2)
#endif

/** Defines whether to use the out-of-band pin to allow the WIFI chip to wake up the MCU. */
#if defined(CY_WIFI_HOST_WAKE_SW_FORCE)
#define CY_USE_OOB_INTR (CY_WIFI_HOST_WAKE_SW_FORCE)
#else
#define CY_USE_OOB_INTR (1u)
#endif /* defined(CY_WIFI_HOST_WAKE_SW_FORCE) */

#define CY_WIFI_HOST_WAKE_IRQ_EVENT GPIO_INT_TRIG_LOW
#define DEFAULT_OOB_PIN (0)
#define WLAN_POWER_UP_DELAY_MS (250)
#define WLAN_CBUCK_DISCHARGE_MS (10)

extern whd_resource_source_t resource_ops;

int airoc_wifi_power_on(const struct device *dev);
Loading

0 comments on commit f41933d

Please sign in to comment.