diff --git a/.github/workflows/build-arduino-esp.yml b/.github/workflows/build-arduino-esp.yml
new file mode 100644
index 0000000..c9b49ee
--- /dev/null
+++ b/.github/workflows/build-arduino-esp.yml
@@ -0,0 +1,46 @@
+name: Build Arduino ESP Examples
+
+on:
+ push:
+ branches: ["main"]
+ pull_request:
+ branches: ["main"]
+ schedule:
+ # Build on Mondays at 9am PST every week
+ - cron: '0 17 * * 1'
+
+jobs:
+ build-arduino-esp:
+ runs-on: ubuntu-24.04
+ container: espressif/idf:v5.4
+ strategy:
+ fail-fast: false
+ matrix:
+ example: [arduino-esp32-led-blink-sdk, arduino-esp32-wifi-scan-sdk]
+ swift: [swift-DEVELOPMENT-SNAPSHOT-2025-03-17-a]
+
+ steps:
+ - name: Checkout repo
+ uses: actions/checkout@v4
+
+ - name: Install apt dependencies
+ run: |
+ apt-get -qq update
+ apt-get -qq -y install pkg-config libstdc++6
+
+ - name: Install ${{ matrix.swift }}
+ run: |
+ wget -q https://download.swift.org/development/ubuntu2404/${{ matrix.swift }}/${{ matrix.swift }}-ubuntu24.04.tar.gz
+ tar xzf ${{ matrix.swift }}-ubuntu24.04.tar.gz
+ export PATH="`pwd`/${{ matrix.swift }}-ubuntu24.04/usr/bin/:$PATH"
+ echo "PATH=$PATH" >> $GITHUB_ENV
+ swiftc --version
+
+ - name: Build ${{ matrix.example }}
+ run: |
+ cd $IDF_PATH
+ . ./export.sh
+ cd -
+ cd ${{ matrix.example }}
+ idf.py set-target esp32c6
+ idf.py build
diff --git a/README.md b/README.md
index 22199d9..cb7805b 100644
--- a/README.md
+++ b/README.md
@@ -20,6 +20,8 @@ Each example in this repository contains build and deployment instructions, howe
| Name | Platform | SDK | Description | Photo |
| ---- | -------- | --- | ----------- | ----- |
+| [arduino-esp32-led-blink-sdk](./arduino-esp32-led-blink-sdk) | ESP32-C6-DevKitC-1 | ESP-IDF SDK | Blink an LED repeatedly with Swift, the ESP-IDF and the Arduino libraries. | |
+| [arduino-esp32-wifi-scan-sdk](./arduino-esp32-wifi-scan-sdk) | ESP32-C6-DevKitC-1 | ESP-IDF SDK | Scan for WiFi networks using Swift, the ESP-IDF and the Arduino libraries. | |
| [esp32-led-blink-sdk](./esp32-led-blink-sdk) | ESP32-C6-Bug | ESP-IDF SDK | Blink an LED repeatedly with Swift & the ESP-IDF. |
|
| [esp32-led-strip-sdk](./esp32-led-strip-sdk) | ESP32-C6-DevKitC-1 | ESP-IDF SDK | Control NeoPixel LEDs with Swift & the ESP-IDF. |
|
| [harmony](./harmony) | Raspberry Pi Pico W | Pico SDK | A bluetooth speaker and ferrofluidic music visualizer. Firmware, Electrical, and Mechanical designs fully available. |
|
diff --git a/arduino-esp32-led-blink-sdk/CMakeLists.txt b/arduino-esp32-led-blink-sdk/CMakeLists.txt
new file mode 100644
index 0000000..bda6977
--- /dev/null
+++ b/arduino-esp32-led-blink-sdk/CMakeLists.txt
@@ -0,0 +1,6 @@
+# The following lines of boilerplate have to be in your project's
+# CMakeLists in this exact order for cmake to work correctly
+cmake_minimum_required(VERSION 3.5)
+
+include($ENV{IDF_PATH}/tools/cmake/project.cmake)
+project(app-template)
diff --git a/arduino-esp32-led-blink-sdk/README.md b/arduino-esp32-led-blink-sdk/README.md
new file mode 100644
index 0000000..1ad5e52
--- /dev/null
+++ b/arduino-esp32-led-blink-sdk/README.md
@@ -0,0 +1,57 @@
+# arduino-esp32-led-blink-sdk
+
+This example demonstrates how to integrate with the ESP-IDF SDK via CMake and how to use the Arduino GPIO library to control an LED from Swift. This example is specifically made for the RISC-V MCUs from ESP32 (the Xtensa MCUs are not currently supported by Swift).
+
+## Requirements
+
+- Set up **version v5.4** (required for this `arduino-esp32` version) of the [ESP-IDF](https://docs.espressif.com/projects/esp-idf/en/v5.4/esp32/) development environment. Follow the steps in the [ESP32-C6 "Get Started" guide](https://docs.espressif.com/projects/esp-idf/en/v5.4/esp32c6/get-started/index.html).
+ - Make sure you specifically set up development for the RISC-V ESP32-C6, and not the Xtensa based products.
+ - If you have a different version of ESP-IDF installed, make sure to also delete `~/.espressif` before running `install.sh`
+
+```sh
+rm -rf ~/esp-idf ~/.espressif # Remove old installation files
+git clone --recurse-submodules https://github.com/espressif/esp-idf.git ~/esp-idf
+cd ~/esp-idf
+git checkout release/v5.4
+git submodule update --init --recursive
+./install.sh
+idf_tools.py install-python-env
+. ./export.sh
+```
+
+- Before trying to use Swift with the ESP-IDF SDK, make sure your environment works and can build the provided C/C++ sample projects, in particular:
+ - Try building and running the "get-started/blink" example from ESP-IDF written in C.
+
+## Building
+
+- Make sure you have a recent nightly Swift toolchain that has Embedded Swift support.
+- If needed, run export.sh to get access to the idf.py script from ESP-IDF.
+- Specify the nightly toolchain to be used via the `TOOLCHAINS` environment variable and the target board type by using `idf.py set-target`.
+```sh
+cd arduino-esp32-led-blink-sdk
+export TOOLCHAINS=...
+. /export.sh
+idf.py set-target esp32c6
+idf.py build
+```
+
+## Running
+
+- Connect the Esp32-C6-Bug board (or any other board with integrated LED on GPIO pin 8) over a USB cable to your Mac. Alternatively you can just connect external LED to GPIO pin 8 on any other board.
+- Connect RX pin of USB-UART converter to TX0 pin of your board if you need serial output. You may also need to connect GND converter pin to the GND pin of the board.
+- Use `idf.py` to upload the firmware and to run it:
+
+```sh
+idf.py flash
+```
+
+- The LED should be blinking now.
+
+### Simulating in VS Code
+
+- Build the project, to generate binaries for simulation
+- Install [Wokwi for VS Code](https://docs.wokwi.com/vscode/getting-started/).
+- Open the `diagram.json` file.
+- Click the Play button to start simulation.
+- Click the Pause button to freeze simulation and display states of GPIOs.
+
diff --git a/arduino-esp32-led-blink-sdk/diagram.json b/arduino-esp32-led-blink-sdk/diagram.json
new file mode 100644
index 0000000..7d76a53
--- /dev/null
+++ b/arduino-esp32-led-blink-sdk/diagram.json
@@ -0,0 +1,36 @@
+{
+ "version": 1,
+ "author": "",
+ "editor": "wokwi",
+ "parts": [
+ {
+ "type": "board-esp32-c6-devkitc-1",
+ "id": "esp",
+ "top": 0,
+ "left": 0,
+ "attrs": { "builder": "esp-idf" }
+ },
+ {
+ "type": "wokwi-resistor",
+ "id": "r1",
+ "top": 119.15,
+ "left": -76.8,
+ "attrs": { "value": "1000" }
+ },
+ {
+ "type": "wokwi-led",
+ "id": "led1",
+ "top": 25.2,
+ "left": -111.4,
+ "attrs": { "color": "red" }
+ }
+ ],
+ "connections": [
+ [ "esp:TX", "$serialMonitor:RX", "", [] ],
+ [ "esp:RX", "$serialMonitor:TX", "", [] ],
+ [ "r1:2", "esp:8", "red", [ "v0" ] ],
+ [ "r1:1", "led1:A", "red", [ "h0" ] ],
+ [ "led1:C", "esp:GND.1", "black", [ "v0" ] ]
+ ],
+ "dependencies": {}
+}
diff --git a/arduino-esp32-led-blink-sdk/main/BridgingHeader.h b/arduino-esp32-led-blink-sdk/main/BridgingHeader.h
new file mode 100644
index 0000000..c0a1906
--- /dev/null
+++ b/arduino-esp32-led-blink-sdk/main/BridgingHeader.h
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+// This source file is part of the Swift open source project
+//
+// Copyright (c) 2025 Apple Inc. and the Swift project authors.
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+//
+//===----------------------------------------------------------------------===//
+
+// For some reason swiftc's clang++ defines `__UINT32_TYPE__` as `unsigned int` (g++'s x86 behaviour) not `long unsigned int` (g++'s riscv32 behaviour)
+#undef __UINT32_TYPE__
+#undef uint32_t
+#define __UINT32_TYPE__ long unsigned int
+#define uint32_t __UINT32_TYPE__
+#define _UINT32_T_DECLARED
+
+#include
+#include
+
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "driver/gpio.h"
+#include "sdkconfig.h"
+
+#include
diff --git a/arduino-esp32-led-blink-sdk/main/CMakeLists.txt b/arduino-esp32-led-blink-sdk/main/CMakeLists.txt
new file mode 100644
index 0000000..a1314a1
--- /dev/null
+++ b/arduino-esp32-led-blink-sdk/main/CMakeLists.txt
@@ -0,0 +1,73 @@
+# Register the app as an IDF component
+idf_component_register(
+ SRCS /dev/null # We don't have any C++ sources
+ PRIV_INCLUDE_DIRS "."
+ REQUIRES arduino
+)
+
+idf_build_get_property(target IDF_TARGET)
+idf_build_get_property(arch IDF_TARGET_ARCH)
+
+if("${arch}" STREQUAL "xtensa")
+ message(FATAL_ERROR "Not supported target: ${target}")
+endif()
+
+# Extract the -march flag and remove any vendor-specific extensions (_x*)
+string(REGEX MATCH "-march=[^ ]+" march_flag "${CMAKE_C_FLAGS}")
+string(REGEX REPLACE "_x[^ ]*" "" march_flag "${march_flag}")
+
+# Extract the -mabi flag or set a default value if not present
+string(REGEX MATCH "-mabi=[^ ]+" mabi_flag "${CMAKE_C_FLAGS}")
+if("${mabi_flag}" STREQUAL "")
+ set(mabi_flag "-mabi=ilp32")
+endif()
+
+# Clear the default COMPILE_OPTIONS which include a lot of C/C++ specific compiler flags that the Swift compiler will not accept
+get_target_property(var ${COMPONENT_LIB} COMPILE_OPTIONS)
+set_target_properties(${COMPONENT_LIB} PROPERTIES COMPILE_OPTIONS "")
+
+# Compute -Xcc flags to set up the C and C++ header search paths for Swift (for bridging header).
+set(SWIFT_INCLUDES)
+foreach(dir ${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES})
+ string(CONCAT SWIFT_INCLUDES ${SWIFT_INCLUDES} "-Xcc ")
+ string(CONCAT SWIFT_INCLUDES ${SWIFT_INCLUDES} "-I${dir} ")
+endforeach()
+foreach(dir ${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES})
+ string(CONCAT SWIFT_INCLUDES ${SWIFT_INCLUDES} "-Xcc ")
+ string(CONCAT SWIFT_INCLUDES ${SWIFT_INCLUDES} "-I${dir} ")
+endforeach()
+
+# Swift compiler flags to build in Embedded Swift mode, optimize for size, choose the right ISA, ABI, etc.
+target_compile_options(${COMPONENT_LIB} PUBLIC "$<$:SHELL:
+ -target riscv32-none-none-eabi
+ -Xfrontend -function-sections -enable-experimental-feature Embedded -wmo -parse-as-library -Osize -cxx-interoperability-mode=default
+ -Xcc ${march_flag} -Xcc ${mabi_flag} -Xcc -fno-pic -Xcc -fno-pie -Xcc -fno-exceptions
+
+ -pch-output-dir /tmp
+ -Xfrontend -enable-single-module-llvm-emission
+
+ ${SWIFT_INCLUDES}
+
+ -import-bridging-header ${CMAKE_CURRENT_LIST_DIR}/BridgingHeader.h
+ >")
+
+# Enable Swift support in CMake, force Whole Module builds (required by Embedded Swift), and use "CMAKE_Swift_COMPILER_WORKS" to
+# skip the trial compilations which don't (yet) correctly work when cross-compiling.
+set(CMAKE_Swift_COMPILER_WORKS YES)
+set(CMAKE_Swift_COMPILATION_MODE_DEFAULT wholemodule)
+set(CMAKE_Swift_COMPILATION_MODE wholemodule)
+enable_language(Swift)
+
+# List of Swift source files to build.
+target_sources(${COMPONENT_LIB}
+ PRIVATE
+ Main.swift
+ Led.swift
+)
+
+add_custom_command(
+ TARGET ${COMPONENT_LIB}
+ POST_BUILD
+ COMMAND ${CMAKE_OBJCOPY} --remove-section .swift_modhash
+ $ $
+)
diff --git a/arduino-esp32-led-blink-sdk/main/Kconfig.projbuild b/arduino-esp32-led-blink-sdk/main/Kconfig.projbuild
new file mode 100644
index 0000000..94f2f0e
--- /dev/null
+++ b/arduino-esp32-led-blink-sdk/main/Kconfig.projbuild
@@ -0,0 +1,8 @@
+# put here your custom config value
+menu "Example Configuration"
+config LED_BLINK_INTERVAL_MS
+ int "LED blinking interval / ms"
+ default 500
+ help
+ Interval in milliseconds between turning the LED on/off
+endmenu
diff --git a/arduino-esp32-led-blink-sdk/main/Led.swift b/arduino-esp32-led-blink-sdk/main/Led.swift
new file mode 100644
index 0000000..8a50414
--- /dev/null
+++ b/arduino-esp32-led-blink-sdk/main/Led.swift
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+// This source file is part of the Swift open source project
+//
+// Copyright (c) 2025 Apple Inc. and the Swift project authors.
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+//
+//===----------------------------------------------------------------------===//
+
+// A simple "overlay" to provide nicer APIs in Swift
+struct Led {
+ var ledPin: UInt8
+ init(gpioPin: gpio_num_t) {
+ ledPin = UInt8(gpioPin.rawValue)
+ pinMode(ledPin, UInt8(OUTPUT))
+ }
+
+ func setLed(value: Bool) {
+ digitalWrite(ledPin, value ? 1 : 0)
+ }
+}
diff --git a/arduino-esp32-led-blink-sdk/main/Main.swift b/arduino-esp32-led-blink-sdk/main/Main.swift
new file mode 100644
index 0000000..7509e93
--- /dev/null
+++ b/arduino-esp32-led-blink-sdk/main/Main.swift
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// This source file is part of the Swift open source project
+//
+// Copyright (c) 2025 Apple Inc. and the Swift project authors.
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+//
+//===----------------------------------------------------------------------===//
+
+// The code will blink an LED on GPIO8. To change the pin, modify Led(gpioPin: GPIO_NUM_8)
+
+var ledValue: Bool = false
+var led: Led?
+
+@_cdecl("_Z5setupv")
+func setup() {
+ print("Hello from Swift on ESP32-C6!")
+ led = Led(gpioPin: GPIO_NUM_8)
+}
+
+@_cdecl("_Z4loopv")
+func loop() {
+ led?.setLed(value: ledValue)
+ ledValue.toggle() // Toggle the boolean value
+ delay(UInt(CONFIG_LED_BLINK_INTERVAL_MS))
+}
diff --git a/arduino-esp32-led-blink-sdk/main/component.mk b/arduino-esp32-led-blink-sdk/main/component.mk
new file mode 100644
index 0000000..61f8990
--- /dev/null
+++ b/arduino-esp32-led-blink-sdk/main/component.mk
@@ -0,0 +1,8 @@
+#
+# Main component makefile.
+#
+# This Makefile can be left empty. By default, it will take the sources in the
+# src/ directory, compile them and link them into lib(subdirectory_name).a
+# in the build directory. This behaviour is entirely configurable,
+# please read the ESP-IDF documents if you need to do this.
+#
diff --git a/arduino-esp32-led-blink-sdk/main/idf_component.yml b/arduino-esp32-led-blink-sdk/main/idf_component.yml
new file mode 100644
index 0000000..cdf6c3d
--- /dev/null
+++ b/arduino-esp32-led-blink-sdk/main/idf_component.yml
@@ -0,0 +1,19 @@
+## IDF Component Manager Manifest File
+dependencies:
+ # # Put list of dependencies here
+ # # For components maintained by Espressif:
+ # component: "~1.0.0"
+ # # For 3rd party components:
+ # username/component: ">=1.0.0,<2.0.0"
+ # username2/component2:
+ # version: "~1.0.0"
+ # # For transient dependencies `public` flag can be set.
+ # # `public` flag doesn't have an effect dependencies of the `main` component.
+ # # All dependencies of `main` are public by default.
+ # public: true
+
+ ## Required IDF version
+ idf: ">=5.3,<5.5"
+ arduino: # Can't be defined as the espressif/arduino-esp32 shorthand since the library name must be 'arduino' for libraries that depend on it
+ git: https://github.com/espressif/arduino-esp32.git
+ version: 3.2.0
diff --git a/arduino-esp32-led-blink-sdk/sdkconfig.defaults b/arduino-esp32-led-blink-sdk/sdkconfig.defaults
new file mode 100644
index 0000000..d4f9762
--- /dev/null
+++ b/arduino-esp32-led-blink-sdk/sdkconfig.defaults
@@ -0,0 +1,4 @@
+CONFIG_FREERTOS_HZ=1000
+CONFIG_MBEDTLS_PSK_MODES=y
+CONFIG_MBEDTLS_KEY_EXCHANGE_PSK=y
+CONFIG_AUTOSTART_ARDUINO=y
diff --git a/arduino-esp32-led-blink-sdk/wokwi.toml b/arduino-esp32-led-blink-sdk/wokwi.toml
new file mode 100644
index 0000000..ab73f47
--- /dev/null
+++ b/arduino-esp32-led-blink-sdk/wokwi.toml
@@ -0,0 +1,8 @@
+# Wokwi Configuration File
+# Reference: https://docs.wokwi.com/vscode/project-config
+[wokwi]
+version = 1
+firmware = 'build/flasher_args.json'
+elf = 'build/main.elf'
+# gdbServerPort=3333
+
diff --git a/arduino-esp32-wifi-scan-sdk/CMakeLists.txt b/arduino-esp32-wifi-scan-sdk/CMakeLists.txt
new file mode 100644
index 0000000..bda6977
--- /dev/null
+++ b/arduino-esp32-wifi-scan-sdk/CMakeLists.txt
@@ -0,0 +1,6 @@
+# The following lines of boilerplate have to be in your project's
+# CMakeLists in this exact order for cmake to work correctly
+cmake_minimum_required(VERSION 3.5)
+
+include($ENV{IDF_PATH}/tools/cmake/project.cmake)
+project(app-template)
diff --git a/arduino-esp32-wifi-scan-sdk/README.md b/arduino-esp32-wifi-scan-sdk/README.md
new file mode 100644
index 0000000..b7f3389
--- /dev/null
+++ b/arduino-esp32-wifi-scan-sdk/README.md
@@ -0,0 +1,48 @@
+# arduino-esp32-wifi-scan-sdk
+
+This example demonstrates how to integrate with the ESP-IDF SDK via CMake and how to use the Arduino Wi-Fi library to scan for nearby networks from Swift. This example is specifically made for the RISC-V MCUs from ESP32 (the Xtensa MCUs are not currently supported by Swift).
+
+## Requirements
+
+- Set up **version v5.4** (required for this `arduino-esp32` version) of the [ESP-IDF](https://docs.espressif.com/projects/esp-idf/en/v5.4/esp32/) development environment. Follow the steps in the [ESP32-C6 "Get Started" guide](https://docs.espressif.com/projects/esp-idf/en/v5.4/esp32c6/get-started/index.html).
+ - Make sure you specifically set up development for the RISC-V ESP32-C6, and not the Xtensa based products.
+ - If you have a different version of ESP-IDF installed, make sure to also delete `~/.espressif` before running `install.sh`
+
+```sh
+rm -rf ~/esp-idf ~/.espressif # Remove old installation files
+git clone --recurse-submodules https://github.com/espressif/esp-idf.git ~/esp-idf
+cd ~/esp-idf
+git checkout release/v5.4
+git submodule update --init --recursive
+./install.sh
+idf_tools.py install-python-env
+. ./export.sh
+```
+
+- Before trying to use Swift with the ESP-IDF SDK, make sure your environment works and can build the provided C/C++ sample projects, in particular:
+ - Try building and running the "get-started/blink" example from ESP-IDF written in C.
+
+## Building
+
+- Make sure you have a recent nightly Swift toolchain that has Embedded Swift support.
+- If needed, run export.sh to get access to the idf.py script from ESP-IDF.
+- Specify the nightly toolchain to be used via the `TOOLCHAINS` environment variable and the target board type by using `idf.py set-target`.
+```sh
+cd arduino-esp32-wifi-scan-sdk
+export TOOLCHAINS=...
+. /export.sh
+idf.py set-target esp32c6
+idf.py build
+```
+
+## Running
+
+- Connect any board with an ESP32-C6
+- Connect the RX and TX pins of your USB-UART converter to the TX0 and RX0 respective pins of your board. You may also need to connect the GND converter pin to the GND pin of the board.
+- Use `idf.py` to upload the firmware and to run it:
+
+```sh
+idf.py flash monitor
+```
+
+- You should see a list of discovered Wi-Fi APs being printed every 5 seconds
diff --git a/arduino-esp32-wifi-scan-sdk/main/ArduinoString.swift b/arduino-esp32-wifi-scan-sdk/main/ArduinoString.swift
new file mode 100644
index 0000000..a3610a6
--- /dev/null
+++ b/arduino-esp32-wifi-scan-sdk/main/ArduinoString.swift
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+// This source file is part of the Swift open source project
+//
+// Copyright (c) 2025 Apple Inc. and the Swift project authors.
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+//
+//===----------------------------------------------------------------------===//
+
+public typealias ArduinoString = String
+
+extension ArduinoString: CustomStringConvertible {
+ public var description: Swift.String {
+ let size = self.length() + 1
+ let buffer = UnsafeMutablePointer.allocate(capacity: Int(size))
+ self.getBytes(buffer, size)
+ let result = Swift.String(cString: UnsafePointer(buffer))
+ buffer.deallocate()
+ return result
+ }
+}
diff --git a/arduino-esp32-wifi-scan-sdk/main/BridgingHeader.h b/arduino-esp32-wifi-scan-sdk/main/BridgingHeader.h
new file mode 100644
index 0000000..3d6ac7e
--- /dev/null
+++ b/arduino-esp32-wifi-scan-sdk/main/BridgingHeader.h
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// This source file is part of the Swift open source project
+//
+// Copyright (c) 2025 Apple Inc. and the Swift project authors.
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+//
+//===----------------------------------------------------------------------===//
+
+// For some reason swiftc's clang++ defines `__UINT32_TYPE__` as `unsigned int` (g++'s x86 behaviour) not `long unsigned int` (g++'s riscv32 behaviour)
+#undef __UINT32_TYPE__
+#undef uint32_t
+#define __UINT32_TYPE__ long unsigned int
+#define uint32_t __UINT32_TYPE__
+#define _UINT32_T_DECLARED
+
+#include
+#include
+#include
+#include
+
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "driver/gpio.h"
+#include "sdkconfig.h"
+
+#include
+#include
+#include
diff --git a/arduino-esp32-wifi-scan-sdk/main/CMakeLists.txt b/arduino-esp32-wifi-scan-sdk/main/CMakeLists.txt
new file mode 100644
index 0000000..a50a389
--- /dev/null
+++ b/arduino-esp32-wifi-scan-sdk/main/CMakeLists.txt
@@ -0,0 +1,73 @@
+# Register the app as an IDF component
+idf_component_register(
+ SRCS /dev/null # We don't have any C++ sources
+ PRIV_INCLUDE_DIRS "."
+ REQUIRES arduino
+)
+
+idf_build_get_property(target IDF_TARGET)
+idf_build_get_property(arch IDF_TARGET_ARCH)
+
+if("${arch}" STREQUAL "xtensa")
+ message(FATAL_ERROR "Not supported target: ${target}")
+endif()
+
+# Extract the -march flag and remove any vendor-specific extensions (_x*)
+string(REGEX MATCH "-march=[^ ]+" march_flag "${CMAKE_C_FLAGS}")
+string(REGEX REPLACE "_x[^ ]*" "" march_flag "${march_flag}")
+
+# Extract the -mabi flag or set a default value if not present
+string(REGEX MATCH "-mabi=[^ ]+" mabi_flag "${CMAKE_C_FLAGS}")
+if("${mabi_flag}" STREQUAL "")
+ set(mabi_flag "-mabi=ilp32")
+endif()
+
+# Clear the default COMPILE_OPTIONS which include a lot of C/C++ specific compiler flags that the Swift compiler will not accept
+get_target_property(var ${COMPONENT_LIB} COMPILE_OPTIONS)
+set_target_properties(${COMPONENT_LIB} PROPERTIES COMPILE_OPTIONS "")
+
+# Compute -Xcc flags to set up the C and C++ header search paths for Swift (for bridging header).
+set(SWIFT_INCLUDES)
+foreach(dir ${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES})
+ string(CONCAT SWIFT_INCLUDES ${SWIFT_INCLUDES} "-Xcc ")
+ string(CONCAT SWIFT_INCLUDES ${SWIFT_INCLUDES} "-I${dir} ")
+endforeach()
+foreach(dir ${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES})
+ string(CONCAT SWIFT_INCLUDES ${SWIFT_INCLUDES} "-Xcc ")
+ string(CONCAT SWIFT_INCLUDES ${SWIFT_INCLUDES} "-I${dir} ")
+endforeach()
+
+# Swift compiler flags to build in Embedded Swift mode, optimize for size, choose the right ISA, ABI, etc.
+target_compile_options(${COMPONENT_LIB} PUBLIC "$<$:SHELL:
+ -target riscv32-none-none-eabi
+ -Xfrontend -function-sections -enable-experimental-feature Embedded -wmo -parse-as-library -Osize -cxx-interoperability-mode=default
+ -Xcc ${march_flag} -Xcc ${mabi_flag} -Xcc -fno-pic -Xcc -fno-pie -Xcc -fno-exceptions
+
+ -pch-output-dir /tmp
+ -Xfrontend -enable-single-module-llvm-emission
+
+ ${SWIFT_INCLUDES}
+
+ -import-bridging-header ${CMAKE_CURRENT_LIST_DIR}/BridgingHeader.h
+ >")
+
+# Enable Swift support in CMake, force Whole Module builds (required by Embedded Swift), and use "CMAKE_Swift_COMPILER_WORKS" to
+# skip the trial compilations which don't (yet) correctly work when cross-compiling.
+set(CMAKE_Swift_COMPILER_WORKS YES)
+set(CMAKE_Swift_COMPILATION_MODE_DEFAULT wholemodule)
+set(CMAKE_Swift_COMPILATION_MODE wholemodule)
+enable_language(Swift)
+
+# List of Swift source files to build.
+target_sources(${COMPONENT_LIB}
+ PRIVATE
+ Main.swift
+ ArduinoString.swift
+)
+
+add_custom_command(
+ TARGET ${COMPONENT_LIB}
+ POST_BUILD
+ COMMAND ${CMAKE_OBJCOPY} --remove-section .swift_modhash
+ $ $
+)
diff --git a/arduino-esp32-wifi-scan-sdk/main/Kconfig.projbuild b/arduino-esp32-wifi-scan-sdk/main/Kconfig.projbuild
new file mode 100644
index 0000000..befc4ef
--- /dev/null
+++ b/arduino-esp32-wifi-scan-sdk/main/Kconfig.projbuild
@@ -0,0 +1,8 @@
+# put here your custom config value
+menu "Example Configuration"
+config WIFI_SCAN_INTERVAL_MS
+ int "WiFi network scanning interval / ms"
+ default 5000
+ help
+ Interval in milliseconds between scanning for networks
+endmenu
diff --git a/arduino-esp32-wifi-scan-sdk/main/Main.swift b/arduino-esp32-wifi-scan-sdk/main/Main.swift
new file mode 100644
index 0000000..6326eca
--- /dev/null
+++ b/arduino-esp32-wifi-scan-sdk/main/Main.swift
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// This source file is part of the Swift open source project
+//
+// Copyright (c) 2025 Apple Inc. and the Swift project authors.
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+//
+//===----------------------------------------------------------------------===//
+
+@_cdecl("_Z5setupv")
+func setup() {
+ print("Hello from Swift on a ESP32-C6!")
+}
+
+@_cdecl("_Z4loopv")
+func loop() {
+ print("Scanning...")
+ let count = WiFi.scanNetworks(false, true)
+ print("Found \(count) networks:")
+ for i in 0..=1.0.0,<2.0.0"
+ # username2/component2:
+ # version: "~1.0.0"
+ # # For transient dependencies `public` flag can be set.
+ # # `public` flag doesn't have an effect dependencies of the `main` component.
+ # # All dependencies of `main` are public by default.
+ # public: true
+
+ ## Required IDF version
+ idf: ">=5.3,<5.5"
+ arduino: # Can't be defined as the espressif/arduino-esp32 shorthand since the library name must be 'arduino' for libraries that depend on it
+ git: https://github.com/espressif/arduino-esp32.git
+ version: 3.2.0
diff --git a/arduino-esp32-wifi-scan-sdk/sdkconfig.defaults b/arduino-esp32-wifi-scan-sdk/sdkconfig.defaults
new file mode 100644
index 0000000..d4f9762
--- /dev/null
+++ b/arduino-esp32-wifi-scan-sdk/sdkconfig.defaults
@@ -0,0 +1,4 @@
+CONFIG_FREERTOS_HZ=1000
+CONFIG_MBEDTLS_PSK_MODES=y
+CONFIG_MBEDTLS_KEY_EXCHANGE_PSK=y
+CONFIG_AUTOSTART_ARDUINO=y